Skip to content

Commit ec3862e

Browse files
authored
Add files via upload
1 parent ba469bd commit ec3862e

File tree

1 file changed

+292
-0
lines changed

1 file changed

+292
-0
lines changed

Diff for: PyGamesScripts/Reversegram/reversegram_game.py

+292
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
# Import the required modules
2+
3+
import random
4+
import sys
5+
6+
WIDTH = 8 # Board is 8 spaces wide.
7+
HEIGHT = 8 # Board is 8 spaces tall.
8+
9+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
10+
11+
def drawBoard(board): # Print the board passed to this function. Return None.
12+
print(' 12345678')
13+
print(' +--------+')
14+
for y in range(HEIGHT):
15+
print('%s|' % (y+1), end='')
16+
for x in range(WIDTH):
17+
print(board[x][y], end='')
18+
print('|%s' % (y+1))
19+
print(' +--------+')
20+
print(' 12345678')
21+
22+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
23+
24+
def getNewBoard():
25+
# Create a brand-new, blank board data structure.
26+
board = []
27+
for i in range(WIDTH):
28+
board.append([' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '])
29+
return board
30+
31+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
32+
33+
def isValidMove(board, tile, xstart, ystart):
34+
# Return False if the player's move on space xstart, ystart is invalid.
35+
# If it is a valid move, return a list of spaces that would become the player's if they made a move here.
36+
if board[xstart][ystart] != ' ' or not isOnBoard(xstart, ystart):
37+
return False
38+
if tile == 'X':
39+
otherTile = 'O'
40+
else:
41+
otherTile = 'X'
42+
43+
tilesToFlip = []
44+
for xdirection, ydirection in [[0, 1], [1, 1], [1, 0], [1, -1],[0, -1], [-1, -1], [-1, 0], [-1, 1]]:
45+
x, y = xstart, ystart
46+
x += xdirection # First step in the x direction
47+
y += ydirection # First step in the y direction
48+
while isOnBoard(x, y) and board[x][y] == otherTile:
49+
# Keep moving in this x & y direction.
50+
x += xdirection
51+
y += ydirection
52+
if isOnBoard(x, y) and board[x][y] == tile:
53+
# There are pieces to flip over. Go in the reverse direction until we reach the original space, noting all the tiles along the way.
54+
while True:
55+
x -= xdirection
56+
y -= ydirection
57+
if x == xstart and y == ystart:
58+
break
59+
tilesToFlip.append([x, y])
60+
61+
if len(tilesToFlip) == 0: # If no tiles were flipped, this is not a valid move.
62+
return False
63+
return tilesToFlip
64+
65+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
66+
67+
def isOnBoard(x, y):
68+
# Return True if the coordinates are located on the board.
69+
return x >= 0 and x <= WIDTH - 1 and y >= 0 and y <= HEIGHT - 1
70+
71+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
72+
73+
def getBoardWithValidMoves(board, tile):
74+
# Return a new board with periods marking the valid moves the player can make.
75+
boardCopy = getBoardCopy(board)
76+
for x, y in getValidMoves(boardCopy, tile):
77+
boardCopy[x][y] = '.'
78+
return boardCopy
79+
80+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
81+
82+
def getValidMoves(board, tile):
83+
# Return a list of [x,y] lists of valid moves for the given player on the given board.
84+
validMoves = []
85+
for x in range(WIDTH):
86+
for y in range(HEIGHT):
87+
if isValidMove(board, tile, x, y) != False:
88+
validMoves.append([x, y])
89+
return validMoves
90+
91+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
92+
93+
def getScoreOfBoard(board):
94+
# Determine the score by counting the tiles. Return a dictionary with keys 'X' and 'O'.
95+
xscore = 0
96+
oscore = 0
97+
for x in range(WIDTH):
98+
for y in range(HEIGHT):
99+
if board[x][y] == 'X':
100+
xscore += 1
101+
if board[x][y] == 'O':
102+
oscore += 1
103+
return {'X':xscore, 'O':oscore}
104+
105+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
106+
107+
def enterPlayerTile():
108+
# Let the player enter which tile they want to be.
109+
# Return a list with the player's tile as the first item and the computer's tile as the second.
110+
tile = ''
111+
while not (tile == 'X' or tile == 'O'):
112+
print('Do you want to be X or O?')
113+
tile = input().upper()
114+
115+
# The first element in the list is the player's tile, and the second is the computer's tile.
116+
if tile == 'X':
117+
return ['X', 'O']
118+
else:
119+
return ['O', 'X']
120+
121+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
122+
123+
def whoGoesFirst():
124+
# Randomly choose who goes first.
125+
if random.randint(0, 1) == 0:
126+
return 'computer'
127+
else:
128+
return 'player'
129+
130+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
131+
132+
def makeMove(board, tile, xstart, ystart):
133+
# Place the tile on the board at xstart, ystart and flip any of the opponent's pieces.
134+
# Return False if this is an invalid move; True if it is valid.
135+
tilesToFlip = isValidMove(board, tile, xstart, ystart)
136+
137+
if tilesToFlip == False:
138+
return False
139+
140+
board[xstart][ystart] = tile
141+
for x, y in tilesToFlip:
142+
board[x][y] = tile
143+
return True
144+
145+
146+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
147+
148+
def getBoardCopy(board):
149+
# Make a duplicate of the board list and return it.
150+
boardCopy = getNewBoard()
151+
152+
for x in range(WIDTH):
153+
for y in range(HEIGHT):
154+
boardCopy[x][y] = board[x][y]
155+
156+
return boardCopy
157+
158+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
159+
160+
def isOnCorner(x, y):
161+
# Return True if the position is in one of the four corners.
162+
return (x == 0 or x == WIDTH - 1) and (y == 0 or y == HEIGHT - 1)
163+
164+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
165+
166+
def getPlayerMove(board, playerTile):
167+
# Let the player enter their move.
168+
# Return the move as [x, y] (or return the strings 'hints' or 'quit').
169+
DIGITS1TO8 = '1 2 3 4 5 6 7 8'.split()
170+
while True:
171+
print('Enter your move, "quit" to end the game, or "hints" to toggle hints.')
172+
move = input().lower()
173+
if move == 'quit' or move == 'hints':
174+
return move
175+
176+
if len(move) == 2 and move[0] in DIGITS1TO8 and move[1] in DIGITS1TO8:
177+
x = int(move[0]) - 1
178+
y = int(move[1]) - 1
179+
if isValidMove(board, playerTile, x, y) == False:
180+
continue
181+
else:
182+
break
183+
else:
184+
print('That is not a valid move. Enter the column (1-8) and then the row (1-8).')
185+
print('For example, 81 will move on the top-right corner.')
186+
187+
return [x, y]
188+
189+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
190+
191+
def getComputerMove(board, computerTile):
192+
# Given a board and the computer's tile, determine where to
193+
# move and return that move as an [x, y] list.
194+
possibleMoves = getValidMoves(board, computerTile)
195+
random.shuffle(possibleMoves) # Randomize the order of the moves.
196+
197+
# Always go for a corner if available.
198+
for x, y in possibleMoves:
199+
if isOnCorner(x, y):
200+
return [x, y]
201+
202+
# Find the highest-scoring move possible.
203+
bestScore = -1
204+
for x, y in possibleMoves:
205+
boardCopy = getBoardCopy(board)
206+
makeMove(boardCopy, computerTile, x, y)
207+
score = getScoreOfBoard(boardCopy)[computerTile]
208+
if score > bestScore:
209+
bestMove = [x, y]
210+
bestScore = score
211+
return bestMove
212+
213+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
214+
215+
def printScore(board, playerTile, computerTile):
216+
scores = getScoreOfBoard(board)
217+
print('You: %s points. Computer: %s points.' % (scores[playerTile], scores[computerTile]))
218+
219+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
220+
221+
def playGame(playerTile, computerTile):
222+
showHints = False
223+
turn = whoGoesFirst()
224+
print('The ' + turn + ' will go first.')
225+
226+
# Clear the board and place starting pieces.
227+
board = getNewBoard()
228+
board[3][3] = 'X'
229+
board[3][4] = 'O'
230+
board[4][3] = 'O'
231+
board[4][4] = 'X'
232+
233+
while True:
234+
playerValidMoves = getValidMoves(board, playerTile)
235+
computerValidMoves = getValidMoves(board, computerTile)
236+
237+
if playerValidMoves == [] and computerValidMoves == []:
238+
return board # No one can move, so end the game.
239+
240+
elif turn == 'player': # Player's turn
241+
if playerValidMoves != []:
242+
if showHints:
243+
validMovesBoard = getBoardWithValidMoves(board,playerTile)
244+
drawBoard(validMovesBoard)
245+
else:
246+
drawBoard(board)
247+
printScore(board, playerTile, computerTile)
248+
249+
move = getPlayerMove(board, playerTile)
250+
if move == 'quit':
251+
print('Thanks for playing!')
252+
sys.exit() # Terminate the program.
253+
elif move == 'hints':
254+
showHints = not showHints
255+
continue
256+
else:
257+
makeMove(board, playerTile, move[0], move[1])
258+
turn = 'computer'
259+
260+
elif turn == 'computer': # Computer's turn
261+
if computerValidMoves != []:
262+
drawBoard(board)
263+
printScore(board, playerTile, computerTile)
264+
265+
input('Press Enter to see the computer\'s move.')
266+
move = getComputerMove(board, computerTile)
267+
makeMove(board, computerTile, move[0], move[1])
268+
turn = 'player'
269+
270+
#------------------------------------------------------------------------------------------------------------------------------------------------------------
271+
272+
print('Welcome to Reversegam!')
273+
274+
playerTile, computerTile = enterPlayerTile()
275+
276+
while True:
277+
finalBoard = playGame(playerTile, computerTile)
278+
279+
# Display the final score.
280+
drawBoard(finalBoard)
281+
scores = getScoreOfBoard(finalBoard)
282+
print('X scored %s points. O scored %s points.' % (scores['X'], scores['O']))
283+
if scores[playerTile] > scores[computerTile]:
284+
print('You beat the computer by %s points! Congratulations!' %(scores[playerTile] - scores[computerTile]))
285+
elif scores[playerTile] < scores[computerTile]:
286+
print('You lost. The computer beat you by %s points.' %(scores[computerTile] - scores[playerTile]))
287+
else:
288+
print('The game was a tie!')
289+
290+
print('Do you want to play again? (yes or no)')
291+
if not input().lower().startswith('y'):
292+
break

0 commit comments

Comments
 (0)