dannyhammer / twoplayergames Goto Github PK
View Code? Open in Web Editor NEWUndergraduate research into the mechanics of simple two-player games.
Undergraduate research into the mechanics of simple two-player games.
If the player tells them none, player gives up.
If player makes same move twice, then its over.
This method currently has a commented block of "code" showcasing the general idea of what we hope to write. Finishing out this function will allow us to implement other games after passing the appropriate arguments.
In each game include a legal move and then a few examples of illegal moves. This will help Dr. Penland (and others) be able to write more detailed unit tests since we have defined some example asserts.
Currently, the generate_population()
function is hardcoded for the graph coloring game. The concept behind this function is simple: Given a game, generate a population of n
players with random unique strategies.
This seems possible to generalize. As of now, it is hardcoded to accept the number of vertices and colors for a specific graph, and generates random orderings from there.
Possible solution: Implement a RandomInitStrategy
for each game. This RandomInitStrategy
randomly generates a valid strategy for the game being played, based on the ruleset of the game, upon calling its constructor (initializing it).
Unsure whether this will work 100% of the time.
Right now the display_turn_tree function displays the entire tree from N toothpicks. Change this to display between a range, so that the user can view a selected moveset.
Once we have the concrete implementation, now we will abstract the classes to be more generic so that other 2 player games could be made.
Now that each game will generate data in the same dictionary format (keys = board state, values = (playername, move)), it should be possible to create a single csv_writer function that writes game data to a csv.
Rows can be individual games, columns can be the dictionary keys (game states) and the entries will be the player name and move tuples.
Currently, in /generic_classes/
, the classes game.py
, player.py
, referee.py
, and board.py
will not run cohesively.
Goal: Make the game.py
class executable with no errors. It does not have to do anything, just run.
Even though our poster presentation will be online, we should prepare for the kinds of questions that would be asked. The first that came to mind was:
More practice is needed creating plots of the toothpick data. Half a dozen plots (barplot, histogram, etc.) can be used. We should try experimenting with them.
Currently, the generate_population()
function can generate duplicate strategies. There is no method in place to ensure that strategies are unique. This must be implemented.
Things to note:
__eq__()
and __ne__()
for the interfaceThe Game class and all of its attributes need Docstrings.
The Board class and all of its attributes need docstrings.
is_legal
is_winning
play
There should be some viable images from our last project/poster
Just a simple example showcasing a play-by-play on a simple graph, preferably showing player 2 winning.
The Player class and all of its attributes need Docstrings.
Currently, a random CPU-playing has the chance of playing the same move twice even when it has other valid moves. This will cause the Referee to think the CPU has given up, ending its turn and declaring its opponent as the winner. This needs to be reworked so that the CPU will not play the same move twice.
In game.py
there exists the following code in the play()
function:
# Check if the game has been won
if self.referee.is_game_over(self.board):
winner = self.player
If we add functionality to RulesetInterface
via the Referee's declare_winner()
function, we can have it return the winner based on the end-game conditions of the board.
Benefits:
Drawbacks:
Right now it is cumbersome to create and run new games due to the necessary amount of imports.
Possible solution: A single simulate()
function that does the following:
Ruleset
and Strategy
as parameters to make it game-generic (Possibly need to give player 1 and player 2 unique strategies?)Some files, namely the generic classes, have dead code (functions that do nothing). These need to be removed (or implemented)
Rewrite the return value(s) of game
so that the csv files contain easily-parsable and usable information
You could see all of the possible states for a particular game by generating a range of numbers from 0 to the initial state.
For each possible state i, you could record “player_state_i” and “move_state_i” as columns in the .csv file. You can also record winning_player.
For instance, with 3 toothpicks, you would have 7 columns: player_state_3, move_state_3, player_state_2, move_state_2, player_state_1, move_state_1, and winning_player. (Please generate these in a for loop rather than hard-coding them.) If the state did not occur, you can put “none” in player_state_i and “0” in move_state_i.
Use Issues for this kind of thing.
Link to thread explaining problem
In a nutshell:
games <- Parent directory
├── __init__.py <- Module file that stackoverflow told me to add
├── generic_classes
│ ├── __init__,py <- Module file that stackoverflow told me to add
│ ├── ruleset_interface.py <- Interface I am implementing
└── unbalanced_rook
├── __init__,py <- Module file that stackoverflow told me to add
└── rook_ruleset.py <- Class that will implement the interface
I cannot import the RulesetInterface
from generic_classes/
in the rook_ruleset.py
file. I do not know how to fix this, and none of my attempts have worked.
Hold this issue, but once we have a concrete Toothpick takeaway then we can focus on this implementation based on generic classes from the takeaway.
Revisit the fourth rule of the game set up to allow us to include the graph coloring game otherwise, our current understanding of the GCG will not satisfy our requirements.
There may be inaccurate documentation (docstrings, comments, etc) across the takeaway_*.py files. Read through and fix them
Write out the init method for the referee class and the appropriate doc string for the class
Create a bunch of scripts! AlwaysTakeOne
vs AlwaysTakeTwo
on 100 different board sizes, 1,000 games each. Throw in a RandomMove
player. Swap so that TakeOne
goes first on one set, then the same code but with TakeTwo
going first, etc. Make a dozen or so scripts that all differ ever so slightly, so we can begin gathering data.
Add a "Total" column to examples, displaying how many toothpicks are left.
Add who won at the bottom of each game.
A player's move function needs to return a set/stack/list of all possible moves. The player must submit a move by popping from the list (thus removing it from the list). If the Referee returns that the move was invalid, the player will submit another move. If the player runs out of valid moves (i.e. the set/stack/list is empty) it must notify the Referee that it has no valid moves.
The referee class and all of its attributes need Docstrings.
Right now the function display_turn_tree prints out data. Change this to return a complete object with the data printable
Reorganize code so that scripts go in a separate directory and write output csv's to a separate directory. ie
toothpick_takeaway/classes/
toothpick_takeaway/scripts/
toothpick_takeaway/outputs/
The Analysis.ipynb
file contains the functions needed to find optimal choices for Player 1 at every move in the game. Use this information to generate a "smart" strategy for Player 1. We can implement it in the takeaway_strategies.py
file.
The code inside game.py
's play()
method is functional but unsatisfactory. Specifically in regards to determining a winner.
Currently, there are two cases where a winner can be declared:
The declare_winner()
method from the referee
is called once the game is over. This may be able to be rewritten to be cleaner, as declare_winner()
must execute at the end of the game, but should not attempt to update the winner
of the game if case 1 triggered the end of the game.
This may extend to editing the code inside referee.py
's declare_winner()
method as well. That method should also update the winner and loser's win
and loss
counters, respectively. To do this, it must know who the winner and loser are.
Currently, Players are compared by their fitness. However, if both players have an identical fitness, they are said to be at an equal level, regardless of how many games they have played.
Fix: Set it up so that two players with identical fitness will be compared by their number of wins. This should be a simple fix inside the player
class, in the comparison methods.
Finish writing the constructor (init) for the game class
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.