Project 3: Generalized Clue

Group 5:  Alex Nicksay, Jason Winokur, & Yuan Zheng
Programming and Problem Solving
Thursday, November 6, 2003

Introduction:

	"Generalized Clue" was a game that stressed the ability to analyze sets of partial information and the management of "knowledge" to in an attempt to discover unknown information before anyone else.  To win the game, one had to guess the values of some number of hidden items before one's opponents.  Each player possessed a portion of the total number of items, and to gain information about any other items, a player had to ask questions of the various opponents.  We found it very clear that to achieve an advantage in the game, one had to infer some amount of information from the actions of other players.

Overall strategy:

	The development of our player, "Simpsons Clue", can be divided into two phases— designing and optimizing.  In the designing phase, we focused on correctly identifying the  hidden items.  Thus, this early version of our player did not guess until absolutely sure of the values of the hidden cards, where were found through questioning.  In the subsequent optimizing phrase, we attempted to speed the learning process in order to guess sooner, and therefore rank higher.	During the development process, we noticed the following:
	1.	A player can correctly guess the hidden cards in at most (n – k – c) rounds, where
		n is the total number of items, k is the number of hidden items, and c is the 
		number of cards per player, assuming the player relies solely on knowledge
		learned through questioning.
	2.	If one can successfully infer the items held by one or more opponents from their
		questions and answers, one can generate a correct guess far earlier than those 
		players who do not attempt such inference.
	3.	The complexity of inferring data from opponents' actions increases dramatically 
		in proportion to amount of "masking" those opponents use.  Thus, inferring 
		information from an opponent with a naive questioning strategy is a trivial 
		problem, while inferring information from an opponent with even a minimally 
		complex strategy becomes a very difficult proposition.

Development:

Initial Approach
	Initially, our player played extremely conservatively, guessing only when it was one hundred percent positive of the answer.  The player randomly chose one of the opponents to question about a list of items, which was randomly "padded" with several of its own cards to help "mask" the question being asked.  In the obvious interest of efficiency, our player did not ask any given opponent about an item that it already knew the opponent possessed.  Similarly, whenever possible, our player answered questions with items it had previously revealed, a tactic designed to minimize the total amount of knowledge among all opponents.

	One aspect of the game which required a player to act upon less-than-complete information was the "forced guess".  A player was forced to guess the values of the hidden items  when it was the last player in the game, all its opponents having already guessed.  In order to maximize the likelihood of a correct guess under said circumstances, we developed a method of generating the probability of items being held by certain players.  A typical scenario is outlined here:

Player A questions Player B about items (1, 2) and learns Player B holds item 1.
Player A sets the probability of Player B holding item 2 to 0.5.
Player A questions Player B about items (2, 3) and learns Player B holds item 3.
Player A sets the probability of Player B holding item 2 to 0.25.

To ensure accurate information about players other than the opponent currently being questioned, we normalized the entire set of card probabilities any time we updated an entry.  We stored the set in a matrix, in which the values of each column (the items) and row (the players, the group of hidden cards included) of the matrix should sum to 1 and the number of cards per player, respectively.  Ergo, if one entry’s value increased or decreased, the corresponding row and column entries should decrease or increase, respectively, in order to maintain the constant sum required.  We found the probability record to provide useful "clues" when forced to make a guess, but the data generated turned out to be highly unreliable, because the results varied  greatly, depending on the questions our player asked and the responses our opponents gave.  Thus, the probability data was relegated to supporting a forced guess only.

	Two modifications we used to mask our questions from opponent inference were "reduced queries" and "variable padding".  In the "reduced queries" technique, one only asks about the minimum number of unknown cards in order to guarantee a positive response.  For example, if Player A knows that Player B is holding 3 of the 6 total unknown items, Player A only questions Player B about 4 unknown items.  The appropriate number of items to include in one's query is (u – p + 1), where u is the total number of unknown items and p is the number of items one knows the opponent to be holding.  By guaranteeing a positive response, one ensures that one's opponents gain no definite knowledge about the items in one's query, just a probability.  In the "variable padding" technique, one begins with a query of unknown items (e.g.  one generated by the "reduced queries" technique), and one adds a random number of known items to the query.  The number of items to pad could be a purely random number, but we decided to choose a random number not less than 1/3 of the total number of known cards, thereby guaranteeing some relative number of items to be known.  In doing so, one ensures that one's questions become difficult to infer information from, due to the changing size and fact that under almost all circumstances the query will contain some mixture of known and unknown cards, the distinction between being difficult for an opponent to decipher.

	Our initial approach guaranteed our player to obtain correct information about all the opponents’ held items and the hidden cards, if the maximum round of play was greater than the above-stated minimum bound (n – k – c).  While this approach allowed our player to all was guess correctly, it did not provide any clear advantage over the opponents, and the outcome of any given game (early in development) was most often determined by the questioning order and the number of complimentary questions being asked.  Since rank was based upon the order of correct guesses, the approach needed to be improved.  We decided to attempt to gather information implied by other players' questions and responses.

Improved Approach: Inference
	By analyzing the trends of opponent questioning, we noticed that specific players could be associated with certain  patterns.  However, when questioning a given opponent, each player tended to remove the item learned from the last query to the opponent, a natural strategy because one would not want to get the same answer again and again.  So, if a player questioned an opponent about all n cards, it is most likely that the player will ask at most (n – 1) cards to that opponent the next time.  To utilize this information, if we discovered that the number of cards a player asked to the same opponent decrements by one after each round, we inferred that the missing card was given in the response, and therefore, that missing card is not hidden.  To be able to accurately determine the existence of this pattern, one requires a large number of rounds.  Thus, we did not infer any information until some midpoint of the game.  Since each inference requires a full-history search, the process is very time consuming.  Furthermore, inferring after the midpoint of the game provide little to no new information.  Consequently, we decided to infer this data once per game.  Initially, we tried to infer the data when our player had learned the values of half the total number of items.  In testing, this turned out to be too late; almost all the resulting inferred information had already been learned via our questioning.  However, inferring the data when only one quarter of the total items were known proved to be a great success.  During our testing, our player successfully inferred about 5 cards and was thus able to generate a correct guess an average of 40 rounds earlier that would have been possible without using the inference.  Although the successful generation of such an early guess provided our player a huge advantage, the inference was a highly delicate process; any random padding an opponent added to the query can ruin the data. 

	A second form of inference we implemented was based on the assumption that one only questions for items one does not know, because the goal of the game is to gain new information as efficiently (i.e. quickly) as possible.  No matter what kind of padding a player used to avoid opponent inference, upon summing the number of times an item as been queried about, the items most frequently found are most likely to be hidden.  To utilize this assumption, whenever an item was included in a query, we incremented the "count" of that item.  If the number of unknown items drops to (k + 1), where k is the total number of hidden items, we matched the set of "count" values with the unknown list and removed all duplicates.  Of the remaining item, the most frequently queried item is the one most likely to be hidden.  In our testing, this inference was  successful roughly forty percent of the time.  A possible reason for such a low success rate could be that every player tended to query very large sets of items; the number of times items were asksed did not vary significantly.
	
	A third inference we implemented was "singleton search".  In searching through the history,  whenever Player A questions Player B about p cards, and one knows that Player B does not have (p – 1) of those items, then Player B must be holding the remaining item.  "Singleton search" suffered a similar problem to the previous inference—every player tended to query very large sets of items, making the occurrence of singletons very rare.
  
Unimplemented Approaches
	Since inference depends  highly on the questioning and response patterns of opponents, we had the idea of implementing a learning player.  The basis of the such a player would have been two-fold: to more-accurately learn our opponents' patterns and to determine a "best practice" policy.  Over a large number of games, our player would analyze each opponent's strategies, comparing them with what that opponent actually knew.  Hopefully, the statistics of the amassed data would then present some insight into the patterns the opponents used.  For example, given a large enough data set, it would be possible to deduce which players were using the "variable padding" technique and whether or not those players used a minimum number of known items with which to pad.  Secondly, through the course of the games, the learning player would vary certain values, comparing its rank with the rank obtained by using previous values.  After each game, the player would adopt the best values and repeat the process.  After a sufficiently large number of variations, the learning player would settle on the best values.  For example, in determining probability data, our player decreased the probability of an opponent having an item by half, if that opponent did not respond about the item in given query.  Perhaps a fifty percent decrement is not the most accurate value.  Further values that could be varied include the threshold after which to calculate inference (currently after one quarter of the items are known) or the minimum number of known items with which to pad queries (currently a random number above one third of the known items).  Finally, we suspect that the learning player would have been of particular help in performing "doubleton search", an enhanced form of "singleton search" in which matches with (p – 2) items are considered, instead or in addition to (p – 1) items.  The learning player would be able to attempt a large number matches throughout the games and record which types of matches proved to be most valuable.  Given the difficulty of such and implementation and the amount of data required provide useful information, we did not have the time to attempt a learning player at such a late date.

	We also thought of a modification to the inference based upon frequency of item query.  In this modification, we would not use the entire history as a data source, just the history per player.  The most frequently queried items are likely to not be held by the player, while the least frequently queried items are.  Despite the fact a player might pad queries with a random number of items, a sufficiently large number of rounds makes such padding inconsequential.  Because we wanted to ensure our player generated correct guesses first, we did not have as much time as desired to implement inferences that might improve our knowledge gathering.  Thus, little time was devoted to expanding this inference method.  One issue we grappled with was the variation in randomness.  Even slight changes in query randomness dramatically increased our computation complexity and decreased the surety of our analysis.  We were therefore hesitant to adopt this aggressive guessing strategy without further development.

Tournament Result Analysis 

	Our player did fairly well in the tournament.  Overall, our average rank was 3.52, with  the following break-down averages in the various games:
	2 Players	3 Players	5 Players	7 Players	9 Players
	3.74		2.5		2.83		3.38		5.15
Our inferences and conservative strategy generally worked better in games with smaller numbers of players, items per player, and items hidden. (See attached charts for a complete breakdown.)  In the 1 item per player games, we did very well, gaining an average rank of 1.60.  Interestingly we also did well in 8 and 16 items per player games for the middle game sizes (3, 5, 7 players), gaining an average rank of 2.42 and 2.58, respectively.  On the other end of the spectrum, our player did not do particularly badly in any given game type, as one can see, earning an average rank above the median values.  Interestingly, our single worst series of games was with 9 players and 2 items per player, earning an average rank of only 7.  It is clear that our player had some difficultly in the larger games, yet played very competitively in the smaller games.  However, the overall mixed performance of our player, with both high and low rankings across almost combinations of games, is a bit puzzling.
	One possible reason for such an outcome perhaps lies in our player's relative use of the game history.  In smaller games, the history is relatively small.  To use the history effectively, one often needs a large amount of data, however, which may have handicapped those players that relied on the history to ascertain info about their opponents.  Our player, on the other hand, only used the history for specific inferences that did not require a large data set.  In small games, this might have given our player an advantage.
	Other possible reasons range from a bug in the guessing code to misinterpreting opponents' queries.  The later might be particularly applicable because most queries were randomized in some fashion, and such a random factor would necessarily detrimental to our player's strategy in a proportionally random amount.

Conclusion

	We feel that our player, "Simpsons Clue", performed decently overall and excellently in small games.  Our mixture of conservative strategy, analysis, and inference was particularly effective in the latter case, making our player a good "all-around" player with a "speciality", so to speak.  Naturally, if we had had more time, we could have improved on the player, and we had many promising prospects.  However, given the time restraints, we feel that our player produced some interesting developments, and with that, we are pleased.