update: minor update
This commit is contained in:
@@ -0,0 +1,276 @@
|
||||
# algorithm steps
|
||||
#
|
||||
# prerequisites
|
||||
# 01 clear the screen
|
||||
# 02 allow a user to determine the size of the playfield
|
||||
# 03 allow a user to enter names of two players
|
||||
#
|
||||
# 1 clear the screen
|
||||
# 2 print the current state of the game
|
||||
# 3 allow for one player or the other to insert coords
|
||||
# 4 place an 'o' or an 'x' to the coresponding coords
|
||||
# 5 check if the game should end (if someone won)
|
||||
# 5.1 if yes -> end the game
|
||||
# 5.2 if no -> jump to step 1
|
||||
|
||||
import os
|
||||
|
||||
# these global variables are flags
|
||||
end = 0
|
||||
turn = 0
|
||||
error = 0
|
||||
|
||||
# error codes
|
||||
#
|
||||
# 1 - invalid value
|
||||
# 2 - invalid index/position
|
||||
# 3 - index/position occupied
|
||||
|
||||
def init():
|
||||
global end, turn
|
||||
|
||||
# prerequisite 01 -> clear the screen
|
||||
clearScreen()
|
||||
|
||||
# prerequisite 02 -> allow a user to determine the size of the playfield
|
||||
size = None
|
||||
F_printOneMoreTime = 0 # variables starting with 'F_' are flags
|
||||
while size == None:
|
||||
try:
|
||||
size = int(input("Size of the playfield (n*n): "))
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
print("Enter a number")
|
||||
F_printOneMoreTime = 1
|
||||
continue
|
||||
if F_printOneMoreTime == 1:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", size)
|
||||
F_printOneMoreTime = 0
|
||||
if size <= 2:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", size, "(changed to 3*3)")
|
||||
size = 3
|
||||
|
||||
|
||||
# prerequisite 03 -> allow a user to enter names of two players
|
||||
name1 = input("Name of the first player: ")
|
||||
name2 = input("Name of the second player: ")
|
||||
|
||||
pf = [] # pf is shor for PlayField
|
||||
temp = []
|
||||
for i in range(size):
|
||||
for j in range(size):
|
||||
temp.append(' ')
|
||||
pf.append(temp)
|
||||
temp = []
|
||||
|
||||
while end == 0:
|
||||
gameRound(pf, name1, name2)
|
||||
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
|
||||
def gameState(pf, name1, name2):
|
||||
global error
|
||||
|
||||
if error == 1:
|
||||
print("Invalid value")
|
||||
error = 0
|
||||
if error == 2:
|
||||
print("Invalid position")
|
||||
error = 0
|
||||
if error == 3:
|
||||
print("Position occupied")
|
||||
error = 0
|
||||
print(name1, "(o) vs", name2, "(x)")
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print(" ")
|
||||
|
||||
def check(pf):
|
||||
# horizontal checking
|
||||
# 0 is for when 'o's win and 1 is for when 'x's win
|
||||
o = x = 0
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'o':
|
||||
o += 1
|
||||
if pf[i][j] == 'x':
|
||||
x += 1
|
||||
if o >= 3:
|
||||
return 0
|
||||
elif x >= 3:
|
||||
return 1
|
||||
if o < 3 or x < 3:
|
||||
o = x = 0
|
||||
|
||||
# vertical checking
|
||||
o = x = 0
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[j][i] == 'o':
|
||||
o += 1
|
||||
if pf[j][i] == 'x':
|
||||
x += 1
|
||||
if o >= 3:
|
||||
return 0
|
||||
elif x >= 3:
|
||||
return 1
|
||||
if o < 3 or x < 3:
|
||||
o = x = 0
|
||||
|
||||
# diagonal checking
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'o':
|
||||
# only 6 possibilities, so the program will try all of them
|
||||
try:
|
||||
if pf[i-1][j-1] == 'o' and pf[i-2][j-2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'o' and pf[i-2][j+2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j-1] == 'o' and pf[i+2][j-2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j+1] == 'o' and pf[i+2][j+2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j-1] == 'o' and pf[i+1][j+1] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'o' and pf[i+1][j-1] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'x':
|
||||
try:
|
||||
if pf[i-1][j-1] == 'x' and pf[i-2][j-2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'x' and pf[i-2][j+2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j-1] == 'x' and pf[i+2][j-2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j+1] == 'x' and pf[i+2][j+2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j-1] == 'x' and pf[i+1][j+1] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'x' and pf[i+1][j-1] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
# draw checking
|
||||
# 2 is for when a draw occurs
|
||||
count = 0
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'o' or pf[i][j] == 'x':
|
||||
count += 1
|
||||
if count == len(pf)*len(pf):
|
||||
return 2
|
||||
|
||||
def gameRound(pf, name1, name2):
|
||||
global end, turn, error
|
||||
|
||||
# step 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# step 2 -> print the current state of the game
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
# step 3 -> allow for one player or the other to insert coords
|
||||
row = column = None
|
||||
while row == column == None:
|
||||
try:
|
||||
row, column = map(int, input().split())
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
error = 1
|
||||
gameState(pf, name1, name2)
|
||||
continue
|
||||
|
||||
# step 4 -> place an 'o' or an 'x' to the coresponding coords
|
||||
#
|
||||
# only if there isn't another symbol present and the coords are valid
|
||||
# the 'o' or 'x' is determined by the turn variable
|
||||
# - if it is 0, then an 'o' is placed, if it is 1, an 'x' is placed instead
|
||||
# the rows and columns are marked 1, 2 and 3, not 0, 1 and 2 as the indexes
|
||||
# for better user experience
|
||||
if row < 1 or column < 1:
|
||||
error = 2
|
||||
try:
|
||||
if pf[row-1][column-1] != ' ':
|
||||
error = 3
|
||||
elif 1 <= row <= len(pf) and 1 <= column <= len(pf) and error == 0:
|
||||
if turn == 0:
|
||||
pf[row-1][column-1] = 'o'
|
||||
turn = 1
|
||||
elif turn == 1:
|
||||
pf[row-1][column-1] = 'x'
|
||||
turn = 0
|
||||
except IndexError:
|
||||
error = 2
|
||||
|
||||
# step 5 -> check if the game should end (if someone won)
|
||||
won = check(pf)
|
||||
|
||||
if won == 0:
|
||||
# step 5.1 -> if yes -> end the game
|
||||
clearScreen()
|
||||
print("o won!")
|
||||
gameState(pf, name1, name2)
|
||||
end = 1
|
||||
# step 5.2 -> if no -> jump to step 1
|
||||
|
||||
if won == 1:
|
||||
clearScreen()
|
||||
print("x won!")
|
||||
gameState(pf, name1, name2)
|
||||
end = 1
|
||||
|
||||
if won == 2:
|
||||
clearScreen()
|
||||
print("Draw!")
|
||||
gameState(pf, name1, name2)
|
||||
end = 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
Reference in New Issue
Block a user