From cf103bcbb81be04543ef1be65fe4c5e7c6e0ac76 Mon Sep 17 00:00:00 2001 From: Dorian Pula Date: Wed, 13 Aug 2014 00:20:22 -0400 Subject: [PATCH] First pass on converting existing Java game code into Python. --- justcheckers/game/Game.java | 249 -------- justcheckers/game/IPoint.java | 14 - justcheckers/game/Player.java | 145 ----- justcheckers/game/Rulebook.java | 352 ----------- justcheckers/game/{Board.java => board.py} | 40 +- justcheckers/game/game.py | 76 +++ .../game/{GameEngine.java => game_engine.py} | 582 +++++++++--------- justcheckers/game/player.py | 41 ++ justcheckers/game/rules.py | 216 +++++++ settings.gradle | 1 - 10 files changed, 638 insertions(+), 1078 deletions(-) delete mode 100644 justcheckers/game/Game.java delete mode 100644 justcheckers/game/IPoint.java delete mode 100644 justcheckers/game/Player.java delete mode 100644 justcheckers/game/Rulebook.java rename justcheckers/game/{Board.java => board.py} (92%) create mode 100644 justcheckers/game/game.py rename justcheckers/game/{GameEngine.java => game_engine.py} (85%) create mode 100644 justcheckers/game/player.py create mode 100644 justcheckers/game/rules.py delete mode 100755 settings.gradle diff --git a/justcheckers/game/Game.java b/justcheckers/game/Game.java deleted file mode 100644 index b897021..0000000 --- a/justcheckers/game/Game.java +++ /dev/null @@ -1,249 +0,0 @@ -/***************************************************************************** - Board.java -- Container for the state of a game in progress. - ***************************************************************************** - - ***************************************************************************** - This file is part of justCheckers. - - justCheckers is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - justCheckers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with justCheckers. If not, see . - *****************************************************************************/ - -package org.justcheckers.game; - -/** - * The main game handling object of GameLoop. - * - * Objects registering as observers on an instance of GameEngine will be - * notified of a change in either the board state or the turn state. The turn - * will change automatically when a complete move is made. Multiple jumps are - * managed by a call to the makeMove method for each jump segment, and the turn - * will not pass to the other player until the jump sequence is complete. - * - * @author Ross Etchells - * @author Dorian Pula - */ -public class Game { - - // -- Constants ----------------------------------------------------------- - /** State of the game when the dark player wins. */ - public static final int STATE_DARK_VICTORY = 2; - /** State of the game when both players draw. */ - public static final int STATE_GAME_DRAWN = 3; - /** State of the game when game is in progress. */ - public static final int STATE_GAME_IN_PROGRESS = 0; - /** State of the game when the light player wins. */ - public static final int STATE_LIGHT_VICTORY = 1; - - // -- Object Fields ------------------------------------------------------- - /** Represents the dark (usually defending) player. */ - private Player darkPlayer; - /** Contains the current checker board used for the game. */ - private Board gameBoard; - /** Contains the current rules used for playing the game. */ - private Rulebook gameRules; - /** The state of the game. */ - private int gameState; - /** - * This point holds the coordinates of a piece making a jump. Mostly used - * for a piece whose move has not finished after 1 jump. This point is set - * to null if not in use. - */ - private final IPoint jumpInProgress; - /** Represents the light (usually attacking) player. */ - private Player lightPlayer; - /** Represents whose turn it is. */ - private boolean lightPlayerTurn; - - /* - * TODO: Game needs to declare who won or better yet, the state of the game - * to be: in progress, light win, dark win or draw. - */ - - // -- Constructors -------------------------------------------------------- - /** - * Create a new game. Uses the defaults of two unnamed players and the - * American rules. - */ - public Game() { - this(Rulebook.AMERICAN_CHECKERS, new Player(), new Player()); - } - - /** - * Create a new game. Uses the default of two unnamed players. The variant - * (which rules) can be set here. - * - * @param variant - * Which variant of checkers will this game be. - */ - public Game(int variant) { - this(variant, new Player(), new Player()); - } - - /** - * Creates a new game. - * - * @param variant - * The variant of checkers to be played. - * @param light - * The player playing the light side. - * @param dark - * The player playing the dark side. - */ - public Game(int variant, Player light, Player dark) { - // Setup all the components of the game. - this.gameRules = new Rulebook(variant); - this.gameBoard = new Board(this.gameRules); - this.darkPlayer = dark; - this.lightPlayer = light; - - // Setup the board and start the game. - this.lightPlayerTurn = this.gameRules.isLightPlayerFirst(); - this.gameBoard.setupNewGame(); - this.jumpInProgress = null; // No moves in progress yet. - this.gameState = Game.STATE_GAME_IN_PROGRESS; - } - - // TODO: Add a constructor for games already in progress. - - // -- Game methods -------------------------------------------------------- - - /** - * Gets the player playing the dark side. - * - * @return The player playing the dark side. - */ - public Player getDarkPlayer() { - return this.darkPlayer; - } - - // -- Get/Set Methods ------------------------------------------------------ - /** - * Gets the board used for this game. - * - * @return The board used for this game. - */ - public Board getGameBoard() { - return this.gameBoard; - } - - /** - * Gets the rules used for this game. - * - * @return The rules used for this game. - */ - public Rulebook getGameRules() { - return this.gameRules; - } - - /** - * Gets the state of the game. The state is defined by the STATE_* - * constants. - * - * @return The state of the game. - */ - public int getGameState() { - return this.gameState; - } - - /** - * Gets the player playing the light side. - * - * @return The player playing the light side. - */ - public Player getLightPlayer() { - return this.lightPlayer; - } - - /** - * Gets if it is the light player's turn. Returns false if it is the dark - * player's turn. - * - * @return If it is the light player's turn. Returns false if it is the dark - * player's turn. - */ - public boolean isLightPlayerTurn() { - return this.lightPlayerTurn; - } - - /** - * Set the player playing the dark side. - * - * @param player - * The player playing the dark side. - */ - public void setDarkPlayer(Player player) { - this.darkPlayer = player; - } - - /** - * Sets the board used for this game. - * - * @param board - * The board for this game. - */ - public void setGameBoard(Board board) { - this.gameBoard = board; - } - - // -- Private Methods ------------------------------------------------------ - - /** - * Sets the rules used for this game. - * - * @param rules - * The rules used for this game. - */ - public void setGameRules(Rulebook rules) { - this.gameRules = rules; - } - - /** - * Sets the state of the game. The state is defined by the STATE_* - * constants. - * - * @param state - * The state of the game. - */ - public void setGameState(int state) { - this.gameState = state; - } - - /** - * Sets the player playing the light side. - * - * @param player - * The player playing the light side. - */ - public void setLightPlayer(Player player) { - this.lightPlayer = player; - } - - /** - * Sets if it is the light player's turn. Set it to false if its the dark - * player's turn. - * - * @param playerTurn - * If it is the light player's turn. - */ - public void setLightPlayerTurn(boolean playerTurn) { - this.lightPlayerTurn = playerTurn; - } - - /** - * @return the jumpInProgress - */ - public IPoint getJumpInProgress() { - return jumpInProgress; - } -} diff --git a/justcheckers/game/IPoint.java b/justcheckers/game/IPoint.java deleted file mode 100644 index 59e6923..0000000 --- a/justcheckers/game/IPoint.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.justcheckers.game; - -/** - * @author dorian - * Created 2013-04-03 @ 4:59 PM by IntelliJ IDEA. - */ -public interface IPoint { - - public void setX(double x); - public void setY(double y); - public double getX(); - public double getY(); - -} diff --git a/justcheckers/game/Player.java b/justcheckers/game/Player.java deleted file mode 100644 index b211255..0000000 --- a/justcheckers/game/Player.java +++ /dev/null @@ -1,145 +0,0 @@ -/***************************************************************************** - Player.java -- Data objects for maintaining player information. - ***************************************************************************** - - ***************************************************************************** - This file is part of justCheckers. - - justCheckers is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - justCheckers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with justCheckers. If not, see . - *****************************************************************************/ - -package org.justcheckers.game; - -/** - * Manages the information of a single player. - * - * @author Chris Bellini - * @author Dorian Pula - */ -public class Player { - - /** The player's total number of losses. */ - private int gamesLost; - /** The total number of games played by the player. */ - private int gamesPlayed; - /** The player's total number of ties. */ - private int gamesTied; - /** The player's total number of wins. */ - private int gamesWon; - /** The player's name. */ - private final String playerName; - - /** Creates an unnamed player with a blank record. */ - public Player() { - this("Unnamed Player", 0, 0, 0, 0); - } - - /** - * Creates a player with a given name and a blank record. - * - * @param name - * The name of the player. - */ - public Player(String name) { - this(name, 0, 0, 0, 0); - } - - /** - * Creates a player with a given name and record. - * - * @param name - * The name of the player to be created. - * @param wins - * Player's total wins. - * @param losses - * Player's total losses. - * @param ties - * Player's total ties. - * @param played - * Total games played by the player. - */ - public Player(String name, int wins, int losses, int ties, int played) { - this.playerName = name; - this.gamesWon = wins; - this.gamesLost = losses; - this.gamesTied = ties; - this.gamesPlayed = played; - } - - /** Adds a new loss for the player's total losses. */ - public void addLoss() { - this.gamesLost++; - this.gamesPlayed++; - } - - /** Adds a new tie for the player's total ties. */ - public void addTie() { - this.gamesTied++; - this.gamesPlayed++; - } - - /** Adds a new win for the player's total wins. */ - public void addWin() { - this.gamesWon++; - this.gamesPlayed++; - } - - /** - * Gets the player's total losses. - * - * @return The player's total losses. - */ - public int getLosses() { - return this.gamesLost; - } - - /** - * Gets the total number of games played by the player. - * - * @return The total number of games played by the player. - */ - public int getPlayedGames() { - return this.gamesPlayed; - } - - /** - * Gets the player's total score. - * - * @return The player's total score. - */ - public int getTies() { - return this.gamesTied; - } - - /** - * Gets the player's total wins. - * - * @return The player's total wins. - */ - public int getWins() { - return this.gamesWon; - } - - /** - * Prints all the data about the player. - * - * @return A string representing the player's data. - */ - @Override - public String toString() { - return "Name: " + this.playerName + "\n" + "Games: Won " - + this.gamesWon + " Lost " + this.gamesLost + " Tied " - + this.gamesTied; - } -} \ No newline at end of file diff --git a/justcheckers/game/Rulebook.java b/justcheckers/game/Rulebook.java deleted file mode 100644 index 41993fd..0000000 --- a/justcheckers/game/Rulebook.java +++ /dev/null @@ -1,352 +0,0 @@ -/***************************************************************************** - Rulebook.java -- A generic 'rulebook' for a checkers game. - ***************************************************************************** - - ***************************************************************************** - This file is part of justCheckers. - - justCheckers is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - justCheckers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with justCheckers. If not, see . - *****************************************************************************/ - -package org.justcheckers.game; - -/** - * The rules for a game of checkers. This class provides a reference object for - * a game of checkers. This helps deal with the number of variants of checkers. - * One of the goals of justCheckers is to provide the flexibility of choose - * between different kinds of checker variants. This class builds a skeleton of - * the rules by defining what setup, moves, jumps, victory conditions and - * special moves make up a particular variant of checkers. - * - * @author Dorian Pula - * @author Chris Bellini - */ -public class Rulebook { - - // -- Constants ----------------------------------------------------------- - - // Checkers variants. - /** Playing by the American rules. */ - public static final int AMERICAN_CHECKERS = 0; - /** Playing by International (Polish) rules. */ - public static final int INTERNATIONAL_CHECKERS = 1; - /** Playing by the Brazilian rules. */ - public static final int BRAZILIAN_CHECKERS = 2; - /** Playing by the Canadian rules. */ - public static final int CANADIAN_CHECKERS = 3; - /** Playing by Pool (Southern USA) rules. */ - public static final int POOL_CHECKERS = 4; - /** Playing by the Spanish rules. */ - public static final int SPANISH_CHECKERS = 5; - /** Playing by the Russian rules. */ - public static final int RUSSIAN_CHECKERS = 6; - /** Playing by the Italian rules. */ - public static final int ITALIAN_CHECKERS = 7; - /** Playing by Suicide rules. */ - public static final int SUICIDE_CHECKERS = 8; - /** Playing by the Ghanaian rules. */ - public static final int GHANAIAN_CHECKERS = 9; - - // TODO: Implement special rules for these checkers. Version >0.1.1? - // Victory conditions. - /** Victory achieved by capturing all enemy pieces. */ - public static final int CAPTURE_ALL_ENEMIES_VICTORY = 0; - /** - * Victory achieved by capturing all pieces. Only caveat is the three king - * versus one king draw rule: - * - * In many games at the end one adversary has three kings while the other - * one has just one king. In such a case the first adversary must win in - * thirteen moves or the game is declared a draw. (Shamelessly stolen from - * http://en.wikipedia.org/wiki/Draughts). - */ - public static final int SPECIAL_POOL_VICTORY = 1; - /** Victory achieved some bizarre manner. TODO: Figure out Russian checkers. */ - public static final int SPECIAL_RUSSIAN_VICTORY = 2; - /** Victory achieved by losing all your pieces. */ - public static final int SPECIAL_SUICIDE_VICTORY = 3; - /** Victory achieved by not being the first with one piece left. */ - public static final int SPECIAL_GHANAIAN_VICTORY = 4; - - // Checker board sizes. - /** Using a "standard" American checkers board. */ - public static final int STANDARD_BOARD_SIZE = 8; - /** Using an international sized checkers board. */ - public static final int INTERNATIONAL_BOARD_SIZE = 10; - /** Using a Canadian sized checkers board. */ - public static final int CANADIAN_BOARD_SIZE = 12; - - /** The number of variants currently supported. */ - private static final int NUMBER_OF_VARIANTS_SUPPORTED = 2; - - /** The size of the board. */ - private int boardSize; - /** Can kings fly across the board? */ - private boolean canKingsFly; - /** Can pawns capture backwards? */ - private boolean canPawnsJumpBackwards; - - // -- Object Fields -------------------------------------------------------- - /** Stores what kind of checkers variant of rule are we playing? */ - private int checkersVariant; - /** Does the light player start first? */ - private boolean lightPlayerFirst; - /** Is the board mirrored? As in white square lower right corner. */ - private boolean mirroredBoard; - /** Must capture if have opportunity. */ - private boolean mustCapture; - /** Must player capture the highest number of pieces. */ - private boolean mustCaptureMaxium; - /** The type of victory conditions. */ - private int victoryConditions; - - // -- Constructors --------------------------------------------------------- - /** - * Creates a rulebook for a checkers game. We use the American variant rules - * by default. - */ - public Rulebook() { - this(Rulebook.AMERICAN_CHECKERS); - } - - /** - * Creates a rulebook for a checkers game. If a bad/unsupported variant is - * created, the default of American checkers is chosen. - * - * @param variant - * The variant of checkers we will play. - */ - public Rulebook(int variant) { - if (variant >= 0 && variant < Rulebook.NUMBER_OF_VARIANTS_SUPPORTED) { - this.checkersVariant = variant; - } else { - this.checkersVariant = Rulebook.AMERICAN_CHECKERS; - } - this.setUpRules(); - } - - /** - * Returns if kings can fly. That is can kings move as far they wish. - * - * @return If kings can fly. - */ - public boolean canKingsFly() { - return this.canKingsFly; - } - - /** - * Returns if pawns can capture backwards. - * - * @return If pawns can capture backwards. - */ - public boolean canPawnsJumpBackwards() { - return this.canPawnsJumpBackwards; - } - - /** - * Returns the size of the board. - * - * @return The size of the board. - */ - public int getBoardSize() { - return this.boardSize; - } - - // -- Get/set methods ------------------------------------------------------ - /** - * Returns the checkers variant being played. - * - * @return The checkers variant being played. - */ - public int getCheckersVariant() { - return this.checkersVariant; - } - - /** - * Returns the victory conditions of this game. - * - * @return The victory conditions of this game. - */ - public int getVictoryConditions() { - return this.victoryConditions; - } - - /** - * Returns is the board mirrored in this game. - * - * @return Is the board mirrored in this game. - */ - public boolean isBoardMirrored() { - return this.mirroredBoard; - } - - /** - * Returns if the light player starts the game. - * - * @return If the light player starts the game. - */ - public boolean isLightPlayerFirst() { - return this.lightPlayerFirst; - } - - /** - * Returns if you must capture a piece if you can. - * - * @return If you must capture a piece if you can. - */ - public boolean mustCapture() { - return this.mustCapture; - } - - /** - * Returns if you must capture the maximum number of pieces possible. - * - * @return If you must capture the maximum number of pieces possible. - */ - public boolean mustCaptureMaxium() { - return this.mustCaptureMaxium; - } - - // -- Private implementation methods. - /** - * Setups the rules according to what variant of checkers was chosen. - */ - private void setUpRules() { - // Save my sanity. - assert this.checkersVariant >= 0; - assert this.checkersVariant < Rulebook.NUMBER_OF_VARIANTS_SUPPORTED; - - // Set up the rules by the type of variant. - switch (this.checkersVariant) { - case Rulebook.AMERICAN_CHECKERS: - this.boardSize = Rulebook.STANDARD_BOARD_SIZE; - this.canKingsFly = false; - this.canPawnsJumpBackwards = false; - this.lightPlayerFirst = false; - this.mirroredBoard = false; - this.mustCapture = true; - this.mustCaptureMaxium = false; - this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY; - break; - - case Rulebook.INTERNATIONAL_CHECKERS: - this.boardSize = Rulebook.INTERNATIONAL_BOARD_SIZE; - this.canKingsFly = true; - this.canPawnsJumpBackwards = true; - this.lightPlayerFirst = true; - this.mirroredBoard = false; - this.mustCapture = true; - this.mustCaptureMaxium = true; - this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY; - break; - - case Rulebook.BRAZILIAN_CHECKERS: - this.boardSize = Rulebook.STANDARD_BOARD_SIZE; - this.canKingsFly = true; - this.canPawnsJumpBackwards = true; - this.lightPlayerFirst = true; - this.mirroredBoard = false; - this.mustCapture = true; - this.mustCaptureMaxium = true; - this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY; - break; - - case Rulebook.CANADIAN_CHECKERS: - this.boardSize = Rulebook.CANADIAN_BOARD_SIZE; - this.canKingsFly = true; - this.canPawnsJumpBackwards = true; - this.lightPlayerFirst = true; - this.mirroredBoard = false; - this.mustCapture = true; - this.mustCaptureMaxium = false; - this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY; - break; - - case Rulebook.POOL_CHECKERS: - this.boardSize = Rulebook.STANDARD_BOARD_SIZE; - this.canKingsFly = true; - this.canPawnsJumpBackwards = true; - this.lightPlayerFirst = false; - this.mirroredBoard = false; - this.mustCapture = true; - this.mustCaptureMaxium = false; - this.victoryConditions = Rulebook.SPECIAL_POOL_VICTORY; - break; - - case Rulebook.SPANISH_CHECKERS: - this.boardSize = Rulebook.STANDARD_BOARD_SIZE; - this.canKingsFly = true; - this.canPawnsJumpBackwards = false; - this.lightPlayerFirst = true; - this.mirroredBoard = true; - this.mustCapture = true; - this.mustCaptureMaxium = true; - this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY; - break; - - case Rulebook.RUSSIAN_CHECKERS: - // TODO: Needs special freshly-kinged-but-still-can-jump special - // rule. - this.boardSize = Rulebook.STANDARD_BOARD_SIZE; - this.canKingsFly = true; - this.canPawnsJumpBackwards = true; - this.lightPlayerFirst = true; - this.mirroredBoard = false; - this.mustCapture = true; - this.mustCaptureMaxium = false; - this.victoryConditions = Rulebook.SPECIAL_RUSSIAN_VICTORY; - break; - - case Rulebook.ITALIAN_CHECKERS: - // TODO: Special rule on must jump most number of kings per capture. - this.boardSize = Rulebook.STANDARD_BOARD_SIZE; - this.canKingsFly = true; - // TODO: Special rule that pawns can't capture kings. - this.canPawnsJumpBackwards = false; - this.lightPlayerFirst = true; - this.mirroredBoard = true; - this.mustCapture = true; - this.mustCaptureMaxium = true; - this.victoryConditions = Rulebook.CAPTURE_ALL_ENEMIES_VICTORY; - break; - - case Rulebook.SUICIDE_CHECKERS: - // TODO: Needs unconventional setup. - this.boardSize = Rulebook.STANDARD_BOARD_SIZE; - this.canKingsFly = true; - this.canPawnsJumpBackwards = true; - this.lightPlayerFirst = true; - this.mirroredBoard = false; - this.mustCapture = true; - this.mustCaptureMaxium = true; - this.victoryConditions = Rulebook.SPECIAL_SUICIDE_VICTORY; - break; - - case Rulebook.GHANAIAN_CHECKERS: - // TODO: Special forfeit king if passing up a king's capture - // opportunity. - this.boardSize = Rulebook.INTERNATIONAL_BOARD_SIZE; - this.canKingsFly = true; - this.canPawnsJumpBackwards = true; - this.lightPlayerFirst = true; - this.mirroredBoard = true; - this.mustCapture = true; - this.mustCaptureMaxium = false; - this.victoryConditions = Rulebook.SPECIAL_GHANAIAN_VICTORY; - break; - } - - } - -} diff --git a/justcheckers/game/Board.java b/justcheckers/game/board.py similarity index 92% rename from justcheckers/game/Board.java rename to justcheckers/game/board.py index 0e6c6f0..1dc7955 100644 --- a/justcheckers/game/Board.java +++ b/justcheckers/game/board.py @@ -1,25 +1,21 @@ -/***************************************************************************** - Board.java -- Container for the state of the board of a game. - ***************************************************************************** - - ***************************************************************************** - This file is part of justCheckers. - - justCheckers is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - justCheckers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with justCheckers. If not, see . - *****************************************************************************/ - -package org.justcheckers.game; +# +# Copyright (c) 2014 Dorian Pula +# +# justCheckers is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# justCheckers is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with justCheckers. If not, see . +# +# Please share and enjoy! +# /** * Container for the state of the checker board during a game. diff --git a/justcheckers/game/game.py b/justcheckers/game/game.py new file mode 100644 index 0000000..3e9927f --- /dev/null +++ b/justcheckers/game/game.py @@ -0,0 +1,76 @@ +# +# Copyright (c) 2014 Dorian Pula +# +# justCheckers is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# justCheckers is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with justCheckers. If not, see . +# +# Please share and enjoy! +# + +from collections import namedtuple + +from enum import Enum + +from justcheckers.game import rules + +Point = namedtuple('Point', ['x', 'y']) + + +class GameState(Enum): + NOT_STARTED = 0 + LIGHT_MOVE = 1 + DARK_MOVE = 2 + LIGHT_VICTORY = 3 + DARK_VICTORY = 4 + DRAW = 5 + + +class Game(object): + """ + Handles the logic behind the main game loop. + + :author: Ross Etchells + :author: Dorian Pula + """ + + def __init__(self, light_player, + dark_player, + game_board=None, + game_rules=rules.CheckersVariant.American, + game_state=GameState.NOT_STARTED): + """ + Initializes a new checker game + + :param light_player: The attack player. + :param dark_player: The defending player. + :param game_board: The checkerboard to use for the game. + :param game_rules: The set of rules to use. + :param game_state: The state of the game. + :return: A representation of the game board. + """ + + self.light_player = light_player + self.dark_player = dark_player + self.board = game_board + + # TODO Initialize the rulebooks + self.rules = game_rules + self.state = game_state + + def is_light_player_turn(self): + """ + Gets if it is the light player's turn. Returns false if it is the dark player's turn. + + :returns: True if it is the light player's turn. Returns false if it is the dark player's turn. + """ + return self.state in [GameState.LIGHT_MOVE, GameState.LIGHT_VICTORY] diff --git a/justcheckers/game/GameEngine.java b/justcheckers/game/game_engine.py similarity index 85% rename from justcheckers/game/GameEngine.java rename to justcheckers/game/game_engine.py index 7647911..d14c7f2 100644 --- a/justcheckers/game/GameEngine.java +++ b/justcheckers/game/game_engine.py @@ -1,295 +1,287 @@ -/***************************************************************************** - GameEngine.java -- Logic engine for manipulating the state of a game. - ***************************************************************************** - - ***************************************************************************** - This file is part of justCheckers. - - justCheckers is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - justCheckers is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with justCheckers. If not, see . - *****************************************************************************/ - -package org.justcheckers.game; - -/** - * @author dpula - * - */ -public class GameEngine { - - // TODO: Add a constructor for games already in progress. - - // -- Game methods -------------------------------------------------------- - - private static boolean canJump(Game game, int sourceRow, int sourceCol, int targetRow, - int targetCol) { - - // TODO: Implement me. - return false; - } - - /** - * Returns if a piece can or cannot move. This move maybe either be a move - * or a jump. This method is called by a user interface when a user wants to - * moves a piece on screen or over the network. The piece can moved if the - * current state of the game allows for it to do so. - * - * TODO: Add priority for king jumps over pawn jumps for any variants that - * do so. - * - * @param sourceRow - * The row from where the piece is moving from. - * @param sourceCol - * The column from where the piece is moving from. - * @param targetRow - * The row to where the piece is moving to. - * @param targetCol - * The column to where the piece is moving to. - * @return True if the piece can move. False if the piece can not move. - */ - public static boolean canMove(Game game, int sourceRow, int sourceCol, int targetRow, - int targetCol) { - - // A few things to figure out priorities in moving a piece. - boolean legalMove = false; // Is the proposed move/jump legal? - boolean realPositions = false; // Are the positions really on the board? - boolean isJump = false; // Is this a jump? - - // Sanity check. - if (game.getGameBoard().isLegalPosition(sourceRow, sourceCol) - && game.getGameBoard().isLegalPosition(targetRow, targetCol)) { - realPositions = true; - - } - - // Is there a jump in progress? - if (realPositions && game.getJumpInProgress() != null) { - - // Only allow the piece in movement to be moved. - if (sourceRow == game.getJumpInProgress().getY() - && sourceCol == game.getJumpInProgress().getX()) { - legalMove = canJump(game, sourceRow, sourceCol, targetRow, - targetCol); - isJump = true; - } - - } else if (realPositions) { - - // Go with the regular flow, jumps first then "slides". - isJump = canPlayerJump(game); - if (isJump) { - legalMove = canJump(game, sourceRow, sourceCol, targetRow, - targetCol); - } else { - legalMove = canSlide(game, sourceRow, sourceCol, targetRow, - targetCol); - } - - } - - return legalMove; - } - - private static boolean canPlayerJump(Game game) { - // TODO: Implement me. - return false; - } - - private static boolean canSlide(Game game, int sourceRow, int sourceCol, int targetRow, - int targetCol) { - - boolean legalMove = true; - boolean mustJump = canPlayerJump(game); - - // Is the move even on the board? - legalMove = game.getGameBoard().isLegalPosition(sourceRow, sourceCol) - && game.getGameBoard().isLegalPosition(targetRow, targetCol); - - // See if the destination is even empty. - if (legalMove) { - legalMove = game.getGameBoard().isEmpty(targetRow, targetCol); - } - - // If yes, then look if right pieces were chosen. - if (legalMove && !mustJump) { - if (game.isLightPlayerTurn() - && game.getGameBoard().isLight(sourceRow, sourceCol)) { - - // To deal with flying kings. - if (game.getGameBoard().isKing(sourceRow, sourceCol) - && game.getGameRules().canKingsFly()) { - - // FIXME: Fix this! - } else { - // if ((Math.abs(targetRow - sourceRow) == 1) && (Math.abs(targetRow - sourceRow) == 1)) { - // legalMove = false; - // } - } - - // Is the path clear for that move? - - } else if (!game.isLightPlayerTurn() - && game.getGameBoard().isDark(sourceRow, sourceCol)) { - - //TODO: Implement me, sometime. - } else { - legalMove = false; - } - } - - return legalMove; - } - - private static void checkForVictory(Game game) { - // TODO: Implement me. - } - - /** - * Gets if a piece is movable. Returns true if the piece can slide or jump. - * This method only calculates slides to the adjacent positions. Similarly, - * the method only looks at jumping an adjacent enemy piece. This check is - * used by the graphical user interface to determine if a piece can be moved - * either for sliding or jumping. The method is aware of whose turn is it to - * move. - * - * @param row - * The row coordinate of the piece to check. - * @param col - * The column coordinate of the piece to check. - * @return Returns true if the piece can slide or jump in this turn. - */ - public static boolean isMovablePiece(Game game, int row, int col) { - - // Fields for determining of a piece is movable. - boolean moveUpLeft = true; - boolean moveUpRight = true; - boolean moveDownLeft = true; - boolean moveDownRight = true; - - /* - * Checks first if the first colour of piece is being grabbed. Next if - * the piece is blocked by its own pieces. Next if the opponent has - * double blocked off the pieces. Also sanity checks if looking past the - * size of the board. - */ - if (game.isLightPlayerTurn() && game.getGameBoard().isLight(row, col)) { // Light - // player. - - // Can piece move normally? - moveDownLeft = canSlide(game, row, col, row + 1, col - 1); - moveDownRight = canSlide(game, row, col, row + 1, col + 1); - - if (game.getGameBoard().isKing(row, col)) { - moveUpLeft = canSlide(game, row, col, row - 1, col - 1); - moveUpRight = canSlide(game, row, col, row - 1, col + 1); - } else { - moveUpLeft = false; - moveUpRight = false; - } - - // If no slides available try doing the same except for jumps. - if (!moveDownLeft) { - moveDownLeft = canJump(game, row, col, row + 2, col - 2); - } else if (!moveDownRight) { - moveDownRight = canJump(game, row, col, row + 2, col + 2); - } else if (game.getGameBoard().isKing(row, col) - || game.getGameRules().canPawnsJumpBackwards()) { - - if (!moveUpLeft) { - moveUpLeft = canJump(game, row, col, row - 2, col + 2); - } else if (!moveUpRight) { - moveUpRight = canJump(game, row, col, row - 2, col - 2); - } - - } - - return moveUpLeft || moveUpRight || moveDownLeft || moveDownRight; - - } else if (game.isLightPlayerTurn() && game.getGameBoard().isDark(row, col)) { // Dark - // player - - // Can piece move normally? - moveUpLeft = canSlide(game, row, col, row - 1, col - 1); - moveUpRight = canSlide(game, row, col, row - 1, col + 1); - - if (game.getGameBoard().isKing(row, col)) { - moveDownLeft = canSlide(game, row, col, row + 1, col - 1); - moveDownRight = canSlide(game, row, col, row + 1, col + 1); - } else { - moveDownLeft = false; - moveDownRight = false; - } - - // If no slides available try doing the same except for jumps. - if (!moveUpLeft) { - moveUpLeft = canJump(game, row, col, row - 2, col - 2); - } else if (!moveUpRight) { - moveUpRight = canJump(game, row, col, row - 2, col + 2); - } else if (game.getGameBoard().isKing(row, col) - || game.getGameRules().canPawnsJumpBackwards()) { - - if (!moveDownLeft) { - moveDownLeft = canJump(game, row, col, row + 2, col + 2); - } else if (!moveDownRight) { - moveDownRight = canJump(game, row, col, row + 2, col - 2); - } - - } - - return moveUpLeft || moveUpRight || moveDownLeft || moveDownRight; - - } else { - return false; // A wrong coloured piece. - } - - } - - /** - * Moves a pieces from one location to another. This move maybe either be a - * move or a jump. This method is called by a user interface when a user - * moves a piece on screen or over the network. The piece is moved if the - * current state of the game allows for it to do so. - * - * TODO: Add priority for king jumps over pawn jumps for any variants that - * do so. TODO: Implement jumping by piece removal. - * - * @param sourceRow - * The row from where the piece is moving from. - * @param sourceCol - * The column from where the piece is moving from. - * @param targetRow - * The row to where the piece is moving to. - * @param targetCol - * The column to where the piece is moving to. - */ - public static void movePiece(Game game, int sourceRow, int sourceCol, int targetRow, - int targetCol) { - - // If everything checks out... move the piece! - if (canMove(game, sourceRow, sourceCol, targetRow, targetCol)) { - if (game.getJumpInProgress() != null) { - - // TODO: Implement jumping via removing of piece. - game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow, - targetCol); - } else { - game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow, - targetCol); - } - - checkForVictory(game); - } - - } - -} +# +# Copyright (c) 2014 Dorian Pula +# +# justCheckers is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# justCheckers is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with justCheckers. If not, see . +# +# Please share and enjoy! +# + +class GameEngine(object): + + // TODO: Add a constructor for games already in progress. + + // -- Game methods -------------------------------------------------------- + + private static boolean canJump(Game game, int sourceRow, int sourceCol, int targetRow, + int targetCol) { + + // TODO: Implement me. + return false; + } + + /** + * Returns if a piece can or cannot move. This move maybe either be a move + * or a jump. This method is called by a user interface when a user wants to + * moves a piece on screen or over the network. The piece can moved if the + * current state of the game allows for it to do so. + * + * TODO: Add priority for king jumps over pawn jumps for any variants that + * do so. + * + * @param sourceRow + * The row from where the piece is moving from. + * @param sourceCol + * The column from where the piece is moving from. + * @param targetRow + * The row to where the piece is moving to. + * @param targetCol + * The column to where the piece is moving to. + * @return True if the piece can move. False if the piece can not move. + */ + public static boolean canMove(Game game, int sourceRow, int sourceCol, int targetRow, + int targetCol) { + + // A few things to figure out priorities in moving a piece. + boolean legalMove = false; // Is the proposed move/jump legal? + boolean realPositions = false; // Are the positions really on the board? + boolean isJump = false; // Is this a jump? + + // Sanity check. + if (game.getGameBoard().isLegalPosition(sourceRow, sourceCol) + && game.getGameBoard().isLegalPosition(targetRow, targetCol)) { + realPositions = true; + + } + + // Is there a jump in progress? + if (realPositions && game.getJumpInProgress() != null) { + + // Only allow the piece in movement to be moved. + if (sourceRow == game.getJumpInProgress().getY() + && sourceCol == game.getJumpInProgress().getX()) { + legalMove = canJump(game, sourceRow, sourceCol, targetRow, + targetCol); + isJump = true; + } + + } else if (realPositions) { + + // Go with the regular flow, jumps first then "slides". + isJump = canPlayerJump(game); + if (isJump) { + legalMove = canJump(game, sourceRow, sourceCol, targetRow, + targetCol); + } else { + legalMove = canSlide(game, sourceRow, sourceCol, targetRow, + targetCol); + } + + } + + return legalMove; + } + + private static boolean canPlayerJump(Game game) { + // TODO: Implement me. + return false; + } + + private static boolean canSlide(Game game, int sourceRow, int sourceCol, int targetRow, + int targetCol) { + + boolean legalMove = true; + boolean mustJump = canPlayerJump(game); + + // Is the move even on the board? + legalMove = game.getGameBoard().isLegalPosition(sourceRow, sourceCol) + && game.getGameBoard().isLegalPosition(targetRow, targetCol); + + // See if the destination is even empty. + if (legalMove) { + legalMove = game.getGameBoard().isEmpty(targetRow, targetCol); + } + + // If yes, then look if right pieces were chosen. + if (legalMove && !mustJump) { + if (game.isLightPlayerTurn() + && game.getGameBoard().isLight(sourceRow, sourceCol)) { + + // To deal with flying kings. + if (game.getGameBoard().isKing(sourceRow, sourceCol) + && game.getGameRules().canKingsFly()) { + + // FIXME: Fix this! + } else { + // if ((Math.abs(targetRow - sourceRow) == 1) && (Math.abs(targetRow - sourceRow) == 1)) { + // legalMove = false; + // } + } + + // Is the path clear for that move? + + } else if (!game.isLightPlayerTurn() + && game.getGameBoard().isDark(sourceRow, sourceCol)) { + + //TODO: Implement me, sometime. + } else { + legalMove = false; + } + } + + return legalMove; + } + + private static void checkForVictory(Game game) { + // TODO: Implement me. + } + + /** + * Gets if a piece is movable. Returns true if the piece can slide or jump. + * This method only calculates slides to the adjacent positions. Similarly, + * the method only looks at jumping an adjacent enemy piece. This check is + * used by the graphical user interface to determine if a piece can be moved + * either for sliding or jumping. The method is aware of whose turn is it to + * move. + * + * @param row + * The row coordinate of the piece to check. + * @param col + * The column coordinate of the piece to check. + * @return Returns true if the piece can slide or jump in this turn. + */ + public static boolean isMovablePiece(Game game, int row, int col) { + + // Fields for determining of a piece is movable. + boolean moveUpLeft = true; + boolean moveUpRight = true; + boolean moveDownLeft = true; + boolean moveDownRight = true; + + /* + * Checks first if the first colour of piece is being grabbed. Next if + * the piece is blocked by its own pieces. Next if the opponent has + * double blocked off the pieces. Also sanity checks if looking past the + * size of the board. + */ + if (game.isLightPlayerTurn() && game.getGameBoard().isLight(row, col)) { // Light + // player. + + // Can piece move normally? + moveDownLeft = canSlide(game, row, col, row + 1, col - 1); + moveDownRight = canSlide(game, row, col, row + 1, col + 1); + + if (game.getGameBoard().isKing(row, col)) { + moveUpLeft = canSlide(game, row, col, row - 1, col - 1); + moveUpRight = canSlide(game, row, col, row - 1, col + 1); + } else { + moveUpLeft = false; + moveUpRight = false; + } + + // If no slides available try doing the same except for jumps. + if (!moveDownLeft) { + moveDownLeft = canJump(game, row, col, row + 2, col - 2); + } else if (!moveDownRight) { + moveDownRight = canJump(game, row, col, row + 2, col + 2); + } else if (game.getGameBoard().isKing(row, col) + || game.getGameRules().canPawnsJumpBackwards()) { + + if (!moveUpLeft) { + moveUpLeft = canJump(game, row, col, row - 2, col + 2); + } else if (!moveUpRight) { + moveUpRight = canJump(game, row, col, row - 2, col - 2); + } + + } + + return moveUpLeft || moveUpRight || moveDownLeft || moveDownRight; + + } else if (game.isLightPlayerTurn() && game.getGameBoard().isDark(row, col)) { // Dark + // player + + // Can piece move normally? + moveUpLeft = canSlide(game, row, col, row - 1, col - 1); + moveUpRight = canSlide(game, row, col, row - 1, col + 1); + + if (game.getGameBoard().isKing(row, col)) { + moveDownLeft = canSlide(game, row, col, row + 1, col - 1); + moveDownRight = canSlide(game, row, col, row + 1, col + 1); + } else { + moveDownLeft = false; + moveDownRight = false; + } + + // If no slides available try doing the same except for jumps. + if (!moveUpLeft) { + moveUpLeft = canJump(game, row, col, row - 2, col - 2); + } else if (!moveUpRight) { + moveUpRight = canJump(game, row, col, row - 2, col + 2); + } else if (game.getGameBoard().isKing(row, col) + || game.getGameRules().canPawnsJumpBackwards()) { + + if (!moveDownLeft) { + moveDownLeft = canJump(game, row, col, row + 2, col + 2); + } else if (!moveDownRight) { + moveDownRight = canJump(game, row, col, row + 2, col - 2); + } + + } + + return moveUpLeft || moveUpRight || moveDownLeft || moveDownRight; + + } else { + return false; // A wrong coloured piece. + } + + } + + /** + * Moves a pieces from one location to another. This move maybe either be a + * move or a jump. This method is called by a user interface when a user + * moves a piece on screen or over the network. The piece is moved if the + * current state of the game allows for it to do so. + * + * TODO: Add priority for king jumps over pawn jumps for any variants that + * do so. TODO: Implement jumping by piece removal. + * + * @param sourceRow + * The row from where the piece is moving from. + * @param sourceCol + * The column from where the piece is moving from. + * @param targetRow + * The row to where the piece is moving to. + * @param targetCol + * The column to where the piece is moving to. + */ + public static void movePiece(Game game, int sourceRow, int sourceCol, int targetRow, + int targetCol) { + + // If everything checks out... move the piece! + if (canMove(game, sourceRow, sourceCol, targetRow, targetCol)) { + if (game.getJumpInProgress() != null) { + + // TODO: Implement jumping via removing of piece. + game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow, + targetCol); + } else { + game.getGameBoard().movePiece(sourceRow, sourceCol, targetRow, + targetCol); + } + + checkForVictory(game); + } + + } + +} diff --git a/justcheckers/game/player.py b/justcheckers/game/player.py new file mode 100644 index 0000000..fb5eb31 --- /dev/null +++ b/justcheckers/game/player.py @@ -0,0 +1,41 @@ +# +# Copyright (c) 2014 Dorian Pula +# +# justCheckers is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# justCheckers is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with justCheckers. If not, see . +# +# Please share and enjoy! +# + + +class Player(object): + """ + Manages the information of a single player. + + :author: Chris Bellini + :author: Dorian Pula + """ + + def __init__(self, name='Unnamed Player', wins=0, losses=0, ties=0): + self.name = name + self.wins = wins + self.losses = losses + self.ties = ties + + def total_games_played(self): + return self.wins + self.losses + self.ties + + def __str__(self): + return 'Name: {name} \n Games: Won {wins} \ Lost {losses} \ Tied {ties}'.format( + name=self.name, wins=self.wins, losses=self.losses, ties=self.ties + ) diff --git a/justcheckers/game/rules.py b/justcheckers/game/rules.py new file mode 100644 index 0000000..32be3d6 --- /dev/null +++ b/justcheckers/game/rules.py @@ -0,0 +1,216 @@ +# +# Copyright (c) 2014 Dorian Pula +# +# justCheckers is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, +# or (at your option) any later version. +# +# justCheckers is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with justCheckers. If not, see . +# +# Please share and enjoy! +# + +from enum import Enum + + +class CheckersVariant(Enum): + AMERICAN = 0 + INTERNATIONAL = 1 + BRAZILIAN = 2 + CANADIAN = 3 + POOL = 4 + SPANISH = 5 + RUSSIAN = 6 + ITALIAN = 7 + SUICIDE = 8 + GHANAIAN = 9 + + +class Rules(object): + """ + Abstraction of the rules for a game of checkers. + + The rules for a game of checkers. This class provides a reference object for + a game of checkers. This helps deal with the number of variants of checkers. + One of the goals of justCheckers is to provide the flexibility of choose + between different kinds of checker variants. This class builds a skeleton of + the rules by defining what setup, moves, jumps, victory conditions and + special moves make up a particular variant of checkers. + + :author: Dorian Pula + :author: Chris Bellini + """ + + # Victory conditions. + # Victory achieved by capturing all enemy pieces. */ + CAPTURE_ALL_ENEMIES_VICTORY = 0 + + # TODO: Implement special rules for these checkers. Version >0.3? + # Victory achieved by capturing all pieces. Only caveat is the three king + # * versus one king draw rule: + # * + # * In many games at the end one adversary has three kings while the other + # * one has just one king. In such a case the first adversary must win in + # * thirteen moves or the game is declared a draw. (Shamelessly stolen from + # * http://en.wikipedia.org/wiki/Draughts). + # */ + SPECIAL_POOL_VICTORY = 1 + # Victory achieved some bizarre manner. TODO: Figure out Russian checkers. + SPECIAL_RUSSIAN_VICTORY = 2 + # Victory achieved by losing all your pieces. + SPECIAL_SUICIDE_VICTORY = 3 + # Victory achieved by not being the first with one piece left. + SPECIAL_GHANAIAN_VICTORY = 4 + + # TODO Move out into individual implementing Rules. + # Checker board sizes. + # Using a "standard" American checkers board. + STANDARD_BOARD_SIZE = 8 + + def __init__(self, + variant, + board_size=STANDARD_BOARD_SIZE, + kings_jump_multiple_times=True, + pawns_jump_backward=True, + light_player_starts_first=True, + mirrored_board=False, + force_capture=True, + force_capture_maximum=True): + + self.checkers_variant = variant + self.board_size = board_size + + self.can_kings_jump_multiple_times = kings_jump_multiple_times + self.can_pawns_jump_backwards = pawns_jump_backward + + self.does_light_player_start_first = light_player_starts_first + self.is_board_mirrored = mirrored_board + self.is_player_forced_to_capture = force_capture + self.is_player_forced_to_capture_maximum_possible = force_capture_maximum + + def is_player_victorious(self, player, game): + # TODO Check if the player is victorious + # TODO Implement me for the standard capture or block all opponent pieces. + return False + + +class AmericanRules(Rules): + def __init__(self): + super(AmericanRules, self).__init__( + variant=CheckersVariant.AMERICAN, + kings_jump_multiple_times=False, + pawns_jump_backward=False, + light_player_starts_first=False, + force_capture_maximum=False, + ) + + +class InternationalRules(Rules): + INTERNATIONAL_BOARD_SIZE = 10 + + def __init__(self): + super(InternationalRules, self).__init__( + variant=CheckersVariant.INTERNATIONAL, + board_size=self.INTERNATIONAL_BOARD_SIZE, + ) + + +class BrazilianRules(Rules): + def __init__(self): + super(BrazilianRules, self).__init__( + variant=CheckersVariant.BRAZILIAN, + ) + + +class CanadianRules(Rules): + CANADIAN_BOARD_SIZE = 12 + + def __init__(self): + super(CanadianRules, self).__init__( + variant=CheckersVariant.CANADIAN, + board_size=self.CANADIAN_BOARD_SIZE, + force_capture_maximum=False, + ) + + +class PoolRules(Rules): + def __init__(self): + super(PoolRules, self).__init__( + variant=CheckersVariant.POOL, + light_player_starts_first=False, + force_capture_maximum=False, + ) + + def is_player_victorious(self, player, game): + # TODO Check if the player is victorious + # TODO Implement special rules for Pool checkers. + return False + + +class SpanishRules(Rules): + def __init__(self): + super(SpanishRules, self).__init__( + variant=CheckersVariant.SPANISH, + pawns_jump_backward=False, + mirrored_board=True, + ) + + +class RussianRules(Rules): + # TODO: Needs special freshly-kinged-but-still-can-jump special rule. + def __init__(self): + super(RussianRules, self).__init__( + variant=CheckersVariant.RUSSIAN, + force_capture_maximum=False, + ) + + def is_player_victorious(self, player, game): + # TODO Check if the player is victorious + # TODO Implement special rules for Russian checkers. + return False + + +class ItalianRules(Rules): + def __init__(self): + super(ItalianRules, self).__init__( + variant=CheckersVariant.ITALIAN, + pawns_jump_backward=False, + mirrored_board=True, + ) + # TODO: Special rule on must jump most number of kings per capture. + # TODO: Special rule that pawns can't capture kings. + + +class SuicideRules(Rules): + # TODO: Needs unconventional setup. + def __init__(self): + super(SuicideRules, self).__init__( + variant=CheckersVariant.SUICIDE, + ) + + def is_player_victorious(self, player, game): + # TODO Check if the player is victorious + # TODO Implement special rules for suicide checkers. + return False + + +class GhanaianRules(Rules): + # TODO: Special forfeit king if passing up a king's capture opportunity. + def __init__(self): + super(GhanaianRules, self).__init__( + variant=CheckersVariant.GHANAIAN, + mirrored_board=True, + force_capture_maximum=False, + ) + + def is_player_victorious(self, player, game): + # TODO Check if the player is victorious + # TODO Implement special rules for Ghanian checkers. + return False diff --git a/settings.gradle b/settings.gradle deleted file mode 100755 index e8c6ab2..0000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -include 'core', 'console', 'web', 'android', 'desktop' \ No newline at end of file