forked from UWOneLaptop/Checkers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheckers.py
182 lines (146 loc) · 7.15 KB
/
checkers.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
from CheckerBoard import CheckerBoard
from Point import Point
from CheckersGUI import CheckersGUI
from GameState import GameState
from SquareState import SquareState
from Move import Move
import Player
import pygtk
pygtk.require('2.0')
import gtk
import sys
import os
from gettext import gettext as _
class Checkers:
# The Checkboard object. This stores the state of the board
# and contains functions for manipulating it
board = None
# The Checkerboard GUI. This displays the game to the user
# and takes user input
view = None
# The last point clicked by the user
last_clicked = None
# The state of the game (Black's turn, paused, etc)
state = None
# Player objects that take turns moving against each other
# can be AI or human
white_player = None
black_player = None
# Win counts for the two players
white_win_count = 0
black_win_count = 0
# This method is called when the user clicks a box in the GUI. This could be called at any time,
# including times when it is not the players turn. Any human supplied moves come through this
# method. The moves are passed on the Human_Player objects to be validated.
# The widget parameter indicates where the user clicked (widget.row, widget.column)
def player_click(self, widget):
# Look up that status of the cell that the user clicked from the board object
cell = self.board.board[widget.column][widget.row]
# This condition checks is the user is on the second click (already selected a piece
# in their first click). This click is meant to place the piece
if not self.last_clicked==None:
# Look up the piece to move
last_cell = self.board.board[self.last_clicked.column][self.last_clicked.row]
# Store the move into start and end points to be passed to the player
start = Point(self.last_clicked.column, self.last_clicked.row)
end = Point(widget.column, widget.row)
#Make Human Move
if self.state.get_state() == GameState.WhitesTurn and isinstance(self.white_player, Player.Human_Player):
return_code = self.white_player.turn(start, end, self.board, self.state)
self.move(start, end, last_cell, return_code)
# TODO: Send messages for invalid moves or jumps available
elif self.state.get_state() == GameState.BlacksTurn and isinstance(self.black_player, Player.Human_Player):
return_code = self.black_player.turn(start, end, self.board, self.state)
self.move(start, end, last_cell, return_code)
#Make AI Move
if self.state.get_state() == GameState.WhitesTurn and isinstance(self.white_player, Player.AI_Player):
moves = self.board.getAllMoves(self.state)
move = moves.pop()
end = move.pop()
start = move.pop()
last_cell = self.board.board[start.row][start.column]
self.move(start, end, last_cell, self.white_player)
if self.state.get_state() == GameState.BlacksTurn and isinstance(self.black_player, Player.AI_Player):
self.black_player.turn(self.board, self.state)
# Listen for next move
self.last_clicked = None
# If we are here this is the first click. The user is selecting a piece to move. Only
# allow them to select their own pieces. Otherwise ignore the click
elif self.state.get_state() == GameState.WhitesTurn and isinstance(self.white_player, Player.Human_Player):
if cell == SquareState.WHITE:
# Highlight the clicked spot and store it in the last_clicked field
self.view.set_checker(widget.row, widget.column, "highlight_regular", "white")
self.last_clicked = Point(widget.row, widget.column)
elif cell == SquareState.WHITEKING:
self.view.set_checker(widget.row, widget.column, "highlight_king", "white")
self.last_clicked = Point(widget.row, widget.column)
elif self.state.get_state() == GameState.BlacksTurn and isinstance(self.black_player, Player.Human_Player):
if cell == SquareState.BLACK:
self.view.set_checker(widget.row, widget.column, "highlight_regular", "black")
self.last_clicked = Point(widget.row, widget.column)
if cell == SquareState.BLACKKING:
self.view.set_checker(widget.row, widget.column, "hilight_king", "black")
self.last_clicked = Point(widget.row, widget.column)
def move(self, start, end, last_cell, return_code):
#If the move was not valid, unhighlight the previous cell
if return_code == Move.MOVE_INVALID:
if last_cell == SquareState.WHITE:
self.view.set_checker(start.column, start.row, "regular", "white")
elif last_cell == SquareState.WHITEKING:
self.view.set_checker(start.column, start.row, "king", "white")
elif last_cell == SquareState.BLACK:
self.view.set_checker(start.column, start.row, "regular", "black")
elif last_cell == SquareState.BLACKKING:
self.view.set_checker(start.column, start.row, "king", "black")
else:
# Move was successful. Display the old square as empty
self.view.set_checker(start.column, start.row, "none", "none")
#If the piece was kinged, display it as a king
if return_code == Move.KINGED or return_code == Move.JUMPED_AND_KINGED:
if last_cell == SquareState.WHITE:
self.view.set_checker(end.column, end.row, "king", "white")
elif last_cell == SquareState.BLACK:
self.view.set_checker(end.column, end.row, "king", "black")
else:
#Display the piece in the new square
if last_cell == SquareState.WHITE:
self.view.set_checker(end.column, end.row, "regular", "white")
elif last_cell == SquareState.WHITEKING:
self.view.set_checker(end.column, end.row, "king", "white")
elif last_cell == SquareState.BLACK:
self.view.set_checker(end.column, end.row, "regular", "black")
elif last_cell == SquareState.BLACKKING:
self.view.set_checker(end.column, end.row, "king", "black")
#If a piece was jumped, remove it from the board
if return_code == Move.JUMPED or return_code == Move.JUMP_AVAILABLE or return_code == Move.JUMPED_AND_KINGED:
self.view.set_checker((start.column+end.column)/2, (start.row+end.row)/2, "none", "none")
#If there is no jump availble: next turn
if not return_code == Move.JUMP_AVAILABLE:
if self.state.get_state() == GameState.WhitesTurn:
self.state.set_state(GameState.BlacksTurn)
#Check if white won
if self.board.gameOver(self.state):
self.white_win_count = self.white_win_count + 1
self.view.update_counter(self.white_win_count)
self.view.win_color("whites")
self.view.change_turn_color("whites")
else:
self.state.set_state(GameState.WhitesTurn)
if self.board.gameOver(self.state):
self.black_win_count = self.black_win_count + 1
self.view.update_counter(self.black_win_count)
self.view.win_color("blacks")
self.view.change_turn_color("blacks")
def main(self):
gtk.main()
def __init__(self):
self.board = CheckerBoard()
self.view = CheckersGUI(self)
self.state = GameState(GameState.WhitesTurn)
self.white_player = Player.Human_Player(Player.WHITE)
self.black_player = Player.AI_Player(Player.BLACK, self)
self.white_win_count = 0
self.black_win_count = 0
if __name__ == "__main__":
checkers = Checkers()
checkers.main()