Coder Social home page Coder Social logo

dannyhammer / twoplayergames Goto Github PK

View Code? Open in Web Editor NEW
3.0 3.0 2.0 5.05 MB

Undergraduate research into the mechanics of simple two-player games.

Python 9.08% Jupyter Notebook 90.92%
analysis evolution game-theory generic genetic-algorithm graph player-games

twoplayergames's People

Contributors

a-shelton822 avatar andrewpenland avatar dannyhammer avatar okelleydevelopment avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

twoplayergames's Issues

Finish writing the Generic Game Play method

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.

Update the Readmes

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.

Investigate how to generalize the generate_population() function

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.

Make a generalized csv writer

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.

Make each generic game class runnable

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.

Preparing For MAA

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:

  • "what other games would be able to fit your criteria? Why or why not."

Fix generate_population() to not generate duplicate strategies

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:

  • To compare strategies, we may need to implement __eq__() and __ne__() for the interface
  • If the population size requested is smaller than the total number of unique strategies, an error should be displayed
  • Should be as generic as possible

Fix random CPU playing the same move over and over

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.

Add functionality to RulesetInterface to aid in declaring a winner

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:

  • Allows us to alter Rule #4 of our game criteria ("if no player can make a legal move, they lose")
  • Allows us to implement the graph coloring game with minimal changes to our code base

Drawbacks:

  • More code to implement for each new game (shouldn't be too much extra)

Investigate making a generalized `simulate()` function for quickly running new games.

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:

  • Accepts a Ruleset and Strategy as parameters to make it game-generic (Possibly need to give player 1 and player 2 unique strategies?)
  • Accepts an initial game state and bounds for the game board
  • Accepts a number of games to run
  • Imports the necessary files
  • Assembles the game, given the parameters
  • Runs the specified number of games
  • Returns a list/dictionary of the data from each game

Remove dead code

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`

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.

Fix import issues in `rook_ruleset.py` and `rook_strategy.py`

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.

Unbalanced Rook

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 Definition of what is a Game

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.

Fix messy documentation

There may be inaccurate documentation (docstrings, comments, etc) across the takeaway_*.py files. Read through and fix them

Create a bunch of scripts!

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.

Players need a way to determine when they have no moves left

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.

Clean up the code in the Game's play() method

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:

  1. The current player made an illegal move, meaning the opponent wins
  2. The current player made a move that put the board into an end-game state, meaning the player wins

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.

Allow Players to be compared by fitness and wins

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.