Giter Club home page Giter Club logo

sanjego's People

Contributors

dependabot[bot] avatar merkrafter avatar

Watchers

 avatar  avatar  avatar

sanjego's Issues

Split rule sets

Due to a miscommunication concerning the requirements, the rule set must be split in 4 (in addition to #5):

  • players may move their towers on opposing towers only
  • players may move any tower
  • players may move any tower that they control by a majority of bricks
  • players may move towers to all 8 (instead of 4) surrounding fields

(The current implementations is a rule set that combines all of the above rules)

Use opening books

The move ordering using only the immediate game values does not help on the first move(s) as (almost) all moves are equally good. Unfortunately, this is where most of the branching happens. Hence, some more opening assistance is needed. Two ideas come into mind:

implicit opening "book"

Experience shows that moves in the middle of the board are generally more valuable than moves at the border.

  • add/subtract a gaussian-like bias to moves in the middle of the board for the evaluation only

explicit opening book

This needs more investigation, but maybe for sufficiently large boards the first few moves are always the same. In this case they need to be cached and evaluated first for new boards.

  • calculate first few move lines for some boards
  • compare if they are equal
  • save them on the disk
  • load and evaluate them first later on

Refactor Tower.move_on_top_of

This method should be a method of the lower tower and also should be renamed to Tower.attach or similar in order to be aligned with Tower.detach

Factory method to set up a game

Currently, the main function sets up the game and the test functions set up a game independently. Therefore, the main function could use some configuration that the test cases don't cover. This problem should be tackled by a commonly used factory method.

Set up CI

  • run tests

  • check code style

  • deploy to container

  • automate building the result presentation

  • re-create the result presentation after experiments

Refactor RuleSet

RuleSet.player_may_move_tower should be independent of the GameField

Implement SparseGameField

As the alpha_beta_search spends a lot of time for finding the children of the current game_node, there is room for improvement.

         167128391 function calls (166949794 primitive calls) in 130.114 seconds

   Ordered by: cumulative time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000  130.135  130.135 [cProfile internals]
 178598/1    1.412    0.000  130.135  130.135 Searching.py:180(alpha_beta_search)
   178598    0.412    0.000  123.384    0.001 Searching.py:74(children)
   178598    0.811    0.000  122.972    0.001 {built-in method builtins.sorted}
   422744   27.432    0.000  122.111    0.000 Searching.py:39(_children)

One problem is that the game field is represented densely (as a list). This means that all game_field positions must be considered in every call to _children which leads to a lot of overhead, especially in the end game where many positions are empty. A much more efficient way could be to represent the game field as a dict and only iterate over existing towers.

Introduce Moves

A Move is a wrapper around a from_pos and a to_pos in the first place and thus improves readability of the program, but has some more advantages:

  • can be taken back and avoid copying the board in each step of the alpha beta search
  • allow rating moves in addition to boards alone
  • can be propagated up the search tree and reveal the best move line(s)

Increase effectiveness of GameNode._children

The effectiveness of the _children method is defined as the ratio of generated useful positions to all generated positions. In the current implementation, for any from_pos all the to_pos in a 3*3 block around it are generated and then need to be checked whether they are allowed.

In the following, to make things simple, only the maximum effectiveness with a NESW neighbourhood is considered.

Imagine an m*n sized game field. Then there are (m-1)n connections between adjacent towers along one axis and (n-1)m connections in the orthogonal direction, making it at most num_useful_pos = 2*[(m-1)n + (n-1)m] if all towers can be moved by a player on top of all their neighbours.
On the other hand, there are num_total_pos = 9*mn positions generated by the current implementation, hence the maximum_effectiveness(m,n) = num_useful_pos / num_total_pos.
By simplifying this, one gets maximum_effectiveness(m,n) = (4 - 2/m - 2/n)/9 and it becomes obvious that this method will never be able to even cross the 50% mark.

This flaw scales directly with the size of the game field. It might be rewarding to tackle this problem.

MoveList integration tests need to be more flexible

Typically, there is more than one way to play the game optimally.
Therefore, the test cases for the move lists should not test for specific move lines (unless there is only a very small number of variations) but for consistency instead, that is: is this move sequence legal and does the value of the game field after all the moves matches the value returned by the alpha beta search?

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.