Add files via upload
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
# TicTacToe
|
||||
|
||||
A simple CLI TicTacToe-like game written in Python
|
||||
Latest version - v2.1.3
|
||||
|
||||
## Key features
|
||||
|
||||
+ Variable playfield size
|
||||
+ Ability to insert player names
|
||||
|
||||
## Gameplay
|
||||
|
||||
Upon startup, you are prompted to enter the playfield size, for
|
||||
example: you enter `3`, so the playfield area will be 3 rows high
|
||||
and 3 columns wide. Then you enter the name of player one and
|
||||
player two. The first player always begins. 3 by 3 is the smallest
|
||||
possible playfield area size.
|
||||
|
||||
When the game itself starts, you are prompted to enter the coordinates
|
||||
of the field you want your symbol to go into. For example: if your
|
||||
symbol is 'o' and you enter `1 1`, then an 'o' will be placed in the
|
||||
top left corner of the playfield area.
|
||||
|
||||
A game ends, when one player or the other has placed 3 of their symbols
|
||||
in either a horizontal row, a vertical row, or a diagonal row. There
|
||||
can also be a draw, that is, when none of the players have managed
|
||||
to place 3 of their symbols in a row.
|
||||
@@ -0,0 +1,395 @@
|
||||
# TODO - __DONE__ variable symbol count needed to win
|
||||
# - __DONE__ selecting the position of the new symbol by moving a cursor with arrow keys inside the playfield, press return to place the symbol
|
||||
# - when a game ends, the winning symbols will blink a few times
|
||||
|
||||
# add: variable symbol count needed to win, selecting the position of the new symbol by moving a cursor with arrow keys inside the playfield, press return to place the symbol
|
||||
# fix: general bugfixes
|
||||
# update: comments
|
||||
|
||||
# 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
|
||||
# 04 allow a user to determine the symbol count needed to win
|
||||
#
|
||||
# 1 clear the screen
|
||||
# 2 print the current state of the game
|
||||
# 3 allow for one player or the other to insert coords by moving with arrow keys and to put the symbol to the selected place by pressing space
|
||||
# 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
|
||||
from pynput import keyboard
|
||||
from pynput.keyboard import Key, Listener, KeyCode
|
||||
|
||||
# these global variables are flags
|
||||
end = 0
|
||||
turn = 0
|
||||
error = 0
|
||||
|
||||
# misc. global vars
|
||||
_size = 0
|
||||
|
||||
# setting the default cursor position to the left top corner
|
||||
cursorX = cursorY = 0
|
||||
|
||||
# error codes
|
||||
#
|
||||
# 1 - invalid value
|
||||
# 2 - invalid index/position
|
||||
# 3 - index/position occupied
|
||||
|
||||
def init():
|
||||
global end, turn, pf, name1, name2, symbolCount, cursorX, cursorY, size, _size
|
||||
|
||||
# 01 -> clear the screen
|
||||
clearScreen()
|
||||
|
||||
# 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): "))
|
||||
_size = size
|
||||
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
|
||||
|
||||
|
||||
# 03 -> allow a user to enter names of two players
|
||||
name1 = input("Name of the first player: ")
|
||||
name2 = input("Name of the second player: ")
|
||||
|
||||
# 04 -> allow a user to determine the symbol count needed to win
|
||||
symbolCount = None
|
||||
F_printOneMoreTime = 0
|
||||
while symbolCount == None:
|
||||
try:
|
||||
symbolCount = int(input("Number of symbols inline needed to win: "))
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
print("Enter a number")
|
||||
F_printOneMoreTime = 1
|
||||
continue
|
||||
if F_printOneMoreTime == 1:
|
||||
clearScreen()
|
||||
print("Number of symbols inline needed to win:", symbolCount)
|
||||
F_printOneMoreTime = 0
|
||||
|
||||
# creating the playfield
|
||||
pf = [] # pf is shor for PlayField
|
||||
temp = []
|
||||
for i in range(size):
|
||||
for j in range(size):
|
||||
temp.append(' ')
|
||||
pf.append(temp)
|
||||
temp = []
|
||||
|
||||
# setting the hotkeys for moving with the cursor and putting down symbols
|
||||
|
||||
while end == 0:
|
||||
gameRound(pf, name1, name2)
|
||||
|
||||
# clears the screen
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
# detects if a position is inside the playfield
|
||||
def inBound(x):
|
||||
global _size
|
||||
|
||||
if 0 <= x < _size:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
# prints the current state of the game
|
||||
def gameState(pf, name1, name2):
|
||||
global error, cursorX, cursorY
|
||||
|
||||
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)):
|
||||
if cursorX == j and cursorY == i:
|
||||
print(f"#{pf[i][j]}#", end=" ")
|
||||
continue
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print("")
|
||||
|
||||
# checks whether someone has won
|
||||
def check(pf):
|
||||
global symbolCount
|
||||
|
||||
# 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 == symbolCount:
|
||||
return 0
|
||||
elif x == symbolCount:
|
||||
return 1
|
||||
if pf[i][j] == ' ':
|
||||
o = x = 0
|
||||
if o < symbolCount or x < symbolCount:
|
||||
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 == symbolCount:
|
||||
return 0
|
||||
elif x == symbolCount:
|
||||
return 1
|
||||
if pf[j][i] == ' ':
|
||||
o = x = 0
|
||||
if o < symbolCount or x < symbolCount:
|
||||
o = x = 0
|
||||
|
||||
# diagonal checking
|
||||
o = x = 0
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'o':
|
||||
try:
|
||||
if pf[i-1][j-1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i-k][j-k] == 'o':
|
||||
o += 1
|
||||
else:
|
||||
o = 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i-k][j+k] == 'o':
|
||||
o += 1
|
||||
else:
|
||||
o = 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j-1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'o':
|
||||
o += 1
|
||||
else:
|
||||
o = 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j+1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'o':
|
||||
o += 1
|
||||
else:
|
||||
o = 0
|
||||
except IndexError:
|
||||
continue
|
||||
if o >= symbolCount:
|
||||
return 0
|
||||
elif o < symbolCount:
|
||||
o = 0
|
||||
|
||||
if pf[i][j] == 'x':
|
||||
try:
|
||||
if pf[i-1][j-1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i-k][j-k] == 'x':
|
||||
x += 1
|
||||
else:
|
||||
x = 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i-k][j+k] == 'x':
|
||||
x += 1
|
||||
else:
|
||||
x = 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j-1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'x':
|
||||
x += 1
|
||||
else:
|
||||
x = 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j+1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'x':
|
||||
x += 1
|
||||
else:
|
||||
x = 0
|
||||
except IndexError:
|
||||
continue
|
||||
if x >= symbolCount:
|
||||
return 1
|
||||
elif x < symbolCount:
|
||||
x = 0
|
||||
|
||||
# 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 cursorLeft():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX-1) == 1 and inBound(cursorY):
|
||||
cursorX -= 1
|
||||
|
||||
clearScreen()
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorRight():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX+1) == 1 and inBound(cursorY) == 1:
|
||||
cursorX += 1
|
||||
|
||||
clearScreen()
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorUp():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY-1) == 1:
|
||||
cursorY -= 1
|
||||
|
||||
clearScreen()
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorDown():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY+1) == 1:
|
||||
cursorY += 1
|
||||
|
||||
clearScreen()
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def putSymbol():
|
||||
global cursorX, cursorY, turn, pf, name1, name2
|
||||
|
||||
if turn == 0 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'o'
|
||||
turn = 1
|
||||
elif turn == 1 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'x'
|
||||
turn = 0
|
||||
clearScreen()
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def keys(key):
|
||||
global listener
|
||||
|
||||
if key == keyboard.Key.left:
|
||||
cursorLeft()
|
||||
if key == keyboard.Key.right:
|
||||
cursorRight()
|
||||
if key == keyboard.Key.up:
|
||||
cursorUp()
|
||||
if key == keyboard.Key.down:
|
||||
cursorDown()
|
||||
if key == keyboard.Key.space:
|
||||
listener.stop()
|
||||
putSymbol()
|
||||
|
||||
# logic for a round of the game
|
||||
def gameRound(pf, name1, name2):
|
||||
global end, turn, error, listener
|
||||
|
||||
# 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# 2 -> print the current state of the game
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
# 3 -> allow for one player or the other to move with arrow keys and to put the symbol to the selected place by pressing space
|
||||
#
|
||||
# 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
|
||||
with keyboard.Listener(
|
||||
on_press=keys,
|
||||
supress=True
|
||||
) as listener:
|
||||
listener.join()
|
||||
|
||||
# 5 -> check if the game should end (if someone won)
|
||||
won = check(pf)
|
||||
|
||||
if won == 0:
|
||||
# 5.1 -> if yes -> end the game
|
||||
clearScreen()
|
||||
print("o won!")
|
||||
gameState(pf, name1, name2)
|
||||
end = 1
|
||||
# 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
|
||||
|
||||
# driver code
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
@@ -0,0 +1,323 @@
|
||||
# TODO - __DONE__ variable symbol count needed to win
|
||||
# - selecting the position of the new symbol by moving a cursor with arrow keys inside the playfield, press return to place the symbol
|
||||
# - when a game ends, the winning symbols will blink a few times
|
||||
|
||||
# add: variable symbol count needed to win
|
||||
# fix: general bugfixes
|
||||
# update: comments
|
||||
|
||||
# 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
|
||||
# 04 allow a user to determine the symbol count needed to win
|
||||
#
|
||||
# 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, keyboard
|
||||
|
||||
# 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, pf, symbolCount
|
||||
|
||||
# 01 -> clear the screen
|
||||
clearScreen()
|
||||
|
||||
# 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
|
||||
|
||||
|
||||
# 03 -> allow a user to enter names of two players
|
||||
name1 = input("Name of the first player: ")
|
||||
name2 = input("Name of the second player: ")
|
||||
|
||||
# 04 -> allow a user to determine the symbol count needed to win
|
||||
symbolCount = None
|
||||
F_printOneMoreTime = 0
|
||||
while symbolCount == None:
|
||||
try:
|
||||
symbolCount = int(input("Number of symbols inline needed to win: "))
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
print("Enter a number")
|
||||
F_printOneMoreTime = 1
|
||||
continue
|
||||
if F_printOneMoreTime == 1:
|
||||
clearScreen()
|
||||
print("Number of symbols inline needed to win:", symbolCount)
|
||||
F_printOneMoreTime = 0
|
||||
|
||||
# creating the playfield
|
||||
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)
|
||||
|
||||
# clears the screen
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
# detects if a position is inside the playfield
|
||||
def inBound(a, b):
|
||||
global pf
|
||||
|
||||
if len(pf) <= a >= 0 or len(pf) <= b >= 0:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
# prints the current state of the game
|
||||
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(" ")
|
||||
|
||||
# checks whether someone has won
|
||||
def check(pf):
|
||||
global symbolCount
|
||||
|
||||
# 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 == symbolCount:
|
||||
return 0
|
||||
elif x == symbolCount:
|
||||
return 1
|
||||
if pf[i][j] == ' ':
|
||||
o = x = 0
|
||||
if o < symbolCount or x < symbolCount:
|
||||
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 == symbolCount:
|
||||
return 0
|
||||
elif x == symbolCount:
|
||||
return 1
|
||||
if pf[j][i] == ' ':
|
||||
o = x = 0
|
||||
if o < symbolCount or x < symbolCount:
|
||||
o = x = 0
|
||||
|
||||
# diagonal checking
|
||||
o = x = 0
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'o':
|
||||
try:
|
||||
if pf[i-1][j-1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i-k][j-k] == 'o':
|
||||
o += 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i-k][j+k] == 'o':
|
||||
o += 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j-1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'o':
|
||||
o += 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j+1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'o':
|
||||
o += 1
|
||||
except IndexError:
|
||||
continue
|
||||
if o >= symbolCount:
|
||||
return 0
|
||||
elif o < symbolCount:
|
||||
o = 0
|
||||
|
||||
if pf[i][j] == 'x':
|
||||
try:
|
||||
if pf[i-1][j-1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i-k][j-k] == 'x':
|
||||
x += 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i-k][j+k] == 'x':
|
||||
x += 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j-1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'x':
|
||||
x += 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j+1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'x':
|
||||
x += 1
|
||||
except IndexError:
|
||||
continue
|
||||
if x >= symbolCount:
|
||||
return 1
|
||||
elif x < symbolCount:
|
||||
x = 0
|
||||
|
||||
# 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
|
||||
|
||||
# logic for a round of the game
|
||||
def gameRound(pf, name1, name2):
|
||||
global end, turn, error
|
||||
|
||||
# 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# 2 -> print the current state of the game
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
# 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
|
||||
|
||||
# 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
|
||||
|
||||
# 5 -> check if the game should end (if someone won)
|
||||
won = check(pf)
|
||||
|
||||
if won == 0:
|
||||
# 5.1 -> if yes -> end the game
|
||||
clearScreen()
|
||||
print("o won!")
|
||||
gameState(pf, name1, name2)
|
||||
end = 1
|
||||
# 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
|
||||
|
||||
# driver code
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
@@ -0,0 +1,452 @@
|
||||
# TODO -
|
||||
|
||||
# add:
|
||||
# fix:
|
||||
# update:
|
||||
|
||||
# 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
|
||||
# 04 allow a user to determine the symbol count needed to win
|
||||
#
|
||||
# 1 clear the screen
|
||||
# 2 print the current state of the game
|
||||
# 3 allow for one player or the other to insert coords by moving with arrow keys and to put the symbol to the selected place by pressing space
|
||||
# 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, time
|
||||
from pynput import keyboard
|
||||
from pynput.keyboard import Key, Listener, KeyCode
|
||||
|
||||
# these global variables are flags
|
||||
end = 0
|
||||
turn = 0
|
||||
error = 0
|
||||
|
||||
# misc. global vars
|
||||
_size = 0
|
||||
winLine = []
|
||||
cursorX = cursorY = 0 # setting the default cursor position to the left top corner
|
||||
|
||||
# error codes
|
||||
#
|
||||
# 1 - invalid value
|
||||
# 2 - invalid index/position
|
||||
# 3 - index/position occupied
|
||||
|
||||
def init():
|
||||
global end, turn, pf, name1, name2, symbolCount, cursorX, cursorY, size, _size
|
||||
|
||||
# 01 -> clear the screen
|
||||
clearScreen()
|
||||
|
||||
# 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): "))
|
||||
_size = size
|
||||
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 < 3:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", size, "(changed to 3*3)")
|
||||
size = 3
|
||||
_size = size
|
||||
|
||||
|
||||
# 03 -> allow a user to enter names of two players
|
||||
name1 = input("Name of the first player: ")
|
||||
name2 = input("Name of the second player: ")
|
||||
|
||||
# 04 -> allow a user to determine the symbol count needed to win
|
||||
symbolCount = None
|
||||
F_printOneMoreTime = 0
|
||||
while symbolCount == None:
|
||||
try:
|
||||
symbolCount = int(input("Number of symbols inline needed to win: "))
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
print("Enter a number")
|
||||
F_printOneMoreTime = 1
|
||||
continue
|
||||
if F_printOneMoreTime == 1:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", size, "(changed to 3*3)")
|
||||
print("Name of the first player:", name1)
|
||||
print("Name of the second player:", name2)
|
||||
print("Number of symbols inline needed to win:", symbolCount)
|
||||
F_printOneMoreTime = 0
|
||||
if symbolCount > _size >= 0:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", _size)
|
||||
print("Name of the first player:", name1)
|
||||
print("Name of the second player:", name2)
|
||||
print("Number of symbols inline needed to win:", symbolCount, f"(changed to {_size}*{_size})")
|
||||
symbolCount = _size
|
||||
time.sleep(2)
|
||||
|
||||
# creating the playfield
|
||||
pf = [] # pf is shor for PlayField
|
||||
temp = []
|
||||
for i in range(size):
|
||||
for j in range(size):
|
||||
temp.append(' ')
|
||||
pf.append(temp)
|
||||
temp = []
|
||||
|
||||
# setting the hotkeys for moving with the cursor and putting down symbols
|
||||
|
||||
while end == 0:
|
||||
gameRound(pf, name1, name2)
|
||||
|
||||
# clears the screen
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
# detects if a position is inside the playfield
|
||||
def inBound(x):
|
||||
global _size
|
||||
|
||||
if 0 <= x < _size:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def blinkPrint(pf, name1, name2):
|
||||
clearScreen()
|
||||
print(name1, "(o) vs", name2, "(x)")
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if [i, j] in winLine:
|
||||
print("[ ]", end=" ")
|
||||
continue
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print("")
|
||||
time.sleep(0.5)
|
||||
|
||||
def _print(pf, name1, name2, blink = 0):
|
||||
clearScreen()
|
||||
if blink == 2:
|
||||
print("o won!")
|
||||
elif blink == 3:
|
||||
print("x won!")
|
||||
elif blink == 4:
|
||||
print("Draw!")
|
||||
|
||||
print(name1, "(o) vs", name2, "(x)")
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if cursorX == j and cursorY == i and blink == 0:
|
||||
print(f"#{pf[i][j]}#", end=" ")
|
||||
continue
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print("")
|
||||
if blink == 1:
|
||||
time.sleep(0.5)
|
||||
|
||||
# prints the current state of the game
|
||||
def gameState(pf, name1, name2, blink = 0):
|
||||
global error, cursorX, cursorY
|
||||
|
||||
if error == 1:
|
||||
print("Invalid value")
|
||||
error = 0
|
||||
if error == 2:
|
||||
print("Invalid position")
|
||||
error = 0
|
||||
if error == 3:
|
||||
print("Position occupied")
|
||||
error = 0
|
||||
|
||||
if blink == 1:
|
||||
for i in range(6):
|
||||
if i % 2 == 0:
|
||||
blinkPrint(pf, name1, name2)
|
||||
if i % 2 == 1:
|
||||
_print(pf, name1, name2, 1)
|
||||
elif blink == 0:
|
||||
_print(pf, name1, name2)
|
||||
elif blink == 2:
|
||||
_print(pf, name1, name2, 2)
|
||||
elif blink == 3:
|
||||
_print(pf, name1, name2, 3)
|
||||
elif blink == 4:
|
||||
_print(pf, name1, name2, 4)
|
||||
|
||||
# checks whether someone has won
|
||||
def check(pf):
|
||||
global symbolCount, winLine
|
||||
|
||||
winLine = []
|
||||
|
||||
# horizontal checking
|
||||
# 0 is for when 'o's win and 1 is for when 'x's win
|
||||
temp = []
|
||||
o = x = 0
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if pf[i][j] == 'o':
|
||||
temp.append([i, j])
|
||||
o += 1
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'x':
|
||||
temp = []
|
||||
o = 0
|
||||
if o < symbolCount:
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if pf[i][j] == 'x':
|
||||
temp.append([i, j])
|
||||
x += 1
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'o':
|
||||
temp = []
|
||||
x = 0
|
||||
if x < symbolCount:
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# vertical checking
|
||||
temp = []
|
||||
o = x = 0
|
||||
for j in range(_size):
|
||||
for i in range(_size):
|
||||
if pf[i][j] == 'o':
|
||||
temp.append([i, j])
|
||||
o += 1
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'x':
|
||||
temp = []
|
||||
o = 0
|
||||
if o < symbolCount:
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
for j in range(_size):
|
||||
for i in range(_size):
|
||||
if pf[i][j] == 'x':
|
||||
temp.append([i, j])
|
||||
x += 1
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'o':
|
||||
temp = []
|
||||
x = 0
|
||||
if x < symbolCount:
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# diagonal checking
|
||||
temp = []
|
||||
o = x = 0
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'o':
|
||||
try:
|
||||
if pf[i+1][j-1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'o' and 0 <= i+k < _size and 0 <= j-k < _size:
|
||||
temp.append([i+k, j-k])
|
||||
o += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
if pf[i+1][j+1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'o' and 0 <= i+k < _size and 0 <= j+k < _size:
|
||||
temp.append([i+k, j+k])
|
||||
o += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
except IndexError:
|
||||
pass
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
elif o < symbolCount:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
if pf[i][j] == 'x':
|
||||
try:
|
||||
if pf[i+1][j-1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'x' and 0 <= i+k < _size and 0 <= j-k < _size:
|
||||
temp.append([i+k, j-k])
|
||||
x += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
if pf[i+1][j+1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'x' and 0 <= i+k < _size and 0 <= j+k < _size:
|
||||
temp.append([i+k, j+k])
|
||||
x += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
except IndexError:
|
||||
pass
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
elif x < symbolCount:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# 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 cursorLeft():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX-1) == 1 and inBound(cursorY):
|
||||
cursorX -= 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorRight():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX+1) == 1 and inBound(cursorY) == 1:
|
||||
cursorX += 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorUp():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY-1) == 1:
|
||||
cursorY -= 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorDown():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY+1) == 1:
|
||||
cursorY += 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def putSymbol():
|
||||
global cursorX, cursorY, turn, pf, name1, name2
|
||||
|
||||
if turn == 0 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'o'
|
||||
turn = 1
|
||||
elif turn == 1 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'x'
|
||||
turn = 0
|
||||
clearScreen()
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def keys(key):
|
||||
global listener
|
||||
|
||||
if key == keyboard.Key.left:
|
||||
cursorLeft()
|
||||
if key == keyboard.Key.right:
|
||||
cursorRight()
|
||||
if key == keyboard.Key.up:
|
||||
cursorUp()
|
||||
if key == keyboard.Key.down:
|
||||
cursorDown()
|
||||
if key == keyboard.Key.space:
|
||||
listener.stop()
|
||||
putSymbol()
|
||||
|
||||
# logic for a round of the game
|
||||
def gameRound(pf, name1, name2):
|
||||
global end, turn, error, listener
|
||||
|
||||
# 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# 2 -> print the current state of the game
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
# 3 -> allow for one player or the other to move with arrow keys and to put the symbol to the selected place by pressing space
|
||||
#
|
||||
# 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
|
||||
with keyboard.Listener(
|
||||
on_press=keys,
|
||||
supress=True
|
||||
) as listener:
|
||||
listener.join()
|
||||
|
||||
# 5 -> check if the game should end (if someone won)
|
||||
won = check(pf)
|
||||
|
||||
if won == 0:
|
||||
# 5.1 -> if yes -> end the game
|
||||
gameState(pf, name1, name2, 1)
|
||||
gameState(pf, name1, name2, 2)
|
||||
end = 1
|
||||
# 5.2 -> if no -> jump to step 1
|
||||
|
||||
if won == 1:
|
||||
gameState(pf, name1, name2, 1)
|
||||
gameState(pf, name1, name2, 3)
|
||||
end = 1
|
||||
|
||||
if won == 2:
|
||||
gameState(pf, name1, name2, 4)
|
||||
end = 1
|
||||
|
||||
# driver code
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
@@ -0,0 +1,7 @@
|
||||
#! /bin/bash
|
||||
rm /home/mnjx/Documents/code/tictactoe/latest/tictactoe-latest.py -f
|
||||
|
||||
ls /home/mnjx/Documents/code/tictactoe/*.py | grep new | xargs cp -t /home/mnjx/Documents/code/tictactoe/latest
|
||||
mv /home/mnjx/Documents/code/tictactoe/latest/*.py /home/mnjx/Documents/code/tictactoe/latest/tictactoe-latest.py
|
||||
|
||||
python /home/mnjx/Documents/code/tictactoe/latest/tictactoe-latest.py
|
||||
@@ -0,0 +1,242 @@
|
||||
# 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
|
||||
|
||||
konec = 0
|
||||
kdoHraje = 0
|
||||
error = 0
|
||||
def init():
|
||||
global konec, kdoHraje
|
||||
|
||||
# prerequisite 01 -> clear the screen
|
||||
clearScreen()
|
||||
|
||||
# prerequisite 02 -> allow a user to determine the size of the playfield
|
||||
size = 0
|
||||
while size == 0:
|
||||
try:
|
||||
size = int(input("Velikost hraciho pole (n*n): "))
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
continue
|
||||
|
||||
|
||||
# prerequisite 03 -> allow a user to enter names of two players
|
||||
jmeno1 = input("Jmeno jednoho hrace: ")
|
||||
jmeno2 = input("Jmeno druheho hrace: ")
|
||||
|
||||
pole = []
|
||||
temp = []
|
||||
for i in range(size):
|
||||
for j in range(size):
|
||||
temp.append(' ')
|
||||
pole.append(temp)
|
||||
temp = []
|
||||
|
||||
while konec == 0:
|
||||
herniKolo(pole, jmeno1, jmeno2)
|
||||
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
|
||||
def vypisHru(pole, jmeno1, jmeno2):
|
||||
global error
|
||||
|
||||
if error == 1:
|
||||
print("Neplatna hodnota policka")
|
||||
error = 0
|
||||
print(jmeno1, "(o) vs", jmeno2, "(x)")
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
print(f"[{pole[i][j]}]", end=" ")
|
||||
print(" ")
|
||||
|
||||
def check(pole):
|
||||
# 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(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'o':
|
||||
o += 1
|
||||
if pole[i][j] == 'x':
|
||||
x += 1
|
||||
if o >= 3:
|
||||
return 0
|
||||
elif x >= 3:
|
||||
return 1
|
||||
|
||||
# vertical checking
|
||||
o = x = 0
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[j][i] == 'o':
|
||||
o += 1
|
||||
if pole[j][i] == 'x':
|
||||
x += 1
|
||||
if o >= 3:
|
||||
return 0
|
||||
elif x >= 3:
|
||||
return 1
|
||||
|
||||
# diagonal checking
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'o':
|
||||
# only 6 possibilities, so the program will try all of them
|
||||
try:
|
||||
if pole[i-1][j-1] == 'o' and pole[i-2][j-2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j+1] == 'o' and pole[i-2][j+2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i+1][j-1] == 'o' and pole[i+2][j-2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i+1][j+1] == 'o' and pole[i+2][j+2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j-1] == 'o' and pole[i+1][j+1] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j+1] == 'o' and pole[i+1][j-1] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'x':
|
||||
try:
|
||||
if pole[i-1][j-1] == 'x' and pole[i-2][j-2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j+1] == 'x' and pole[i-2][j+2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i+1][j-1] == 'x' and pole[i+2][j-2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i+1][j+1] == 'x' and pole[i+2][j+2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j-1] == 'x' and pole[i+1][j+1] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j+1] == 'x' and pole[i+1][j-1] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
# draw checking
|
||||
# 2 is for when a draw occurs
|
||||
pocet = 0
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'o' or pole[i][j] == 'x':
|
||||
pocet += 1
|
||||
if pocet == len(pole)*len(pole):
|
||||
return 2
|
||||
|
||||
def herniKolo(pole, jmeno1, jmeno2):
|
||||
global konec, kdoHraje, error
|
||||
|
||||
# step 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# step 2 -> print the current state of the game
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
|
||||
# step 3 -> allow for one player or the other to insert coords
|
||||
rada = sloupec = 0
|
||||
while rada == sloupec == 0:
|
||||
try:
|
||||
rada, sloupec = map(int, input().split())
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
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 kdoHraje 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
|
||||
try:
|
||||
if pole[rada-1][sloupec-1] == ' ' and 1 <= rada <= len(pole) and 1 <= sloupec <= len(pole):
|
||||
if kdoHraje == 0:
|
||||
pole[rada-1][sloupec-1] = 'o'
|
||||
kdoHraje = 1
|
||||
elif kdoHraje == 1:
|
||||
pole[rada-1][sloupec-1] = 'x'
|
||||
kdoHraje = 0
|
||||
except IndexError:
|
||||
error = 1
|
||||
|
||||
# step 5 -> check if the game should end (if someone won)
|
||||
vyherce = check(pole)
|
||||
|
||||
if vyherce == 0:
|
||||
# step 5.1 -> if yes -> end the game
|
||||
clearScreen()
|
||||
print("Vyhralo o!")
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
konec = 1
|
||||
# step 5.2 -> if no -> jump to step 1
|
||||
|
||||
if vyherce == 1:
|
||||
clearScreen()
|
||||
print("Vyhralo x!")
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
konec = 1
|
||||
|
||||
if vyherce == 2:
|
||||
clearScreen()
|
||||
print("Remiza!")
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
konec = 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
@@ -0,0 +1,255 @@
|
||||
# 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
|
||||
|
||||
konec = 0
|
||||
kdoHraje = 0
|
||||
error = 0
|
||||
def init():
|
||||
global konec, kdoHraje
|
||||
|
||||
# prerequisite 01 -> clear the screen
|
||||
clearScreen()
|
||||
|
||||
# prerequisite 02 -> allow a user to determine the size of the playfield
|
||||
size = None
|
||||
F_printOneMoreTime = 0
|
||||
while size == None:
|
||||
try:
|
||||
size = int(input("Velikost hraciho pole (n*n): "))
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
print("Zadejte cislo")
|
||||
F_printOneMoreTime = 1
|
||||
continue
|
||||
if F_printOneMoreTime == 1:
|
||||
clearScreen()
|
||||
print("Velikost hraciho pole (n*n):", size)
|
||||
F_printOneMoreTime = 0
|
||||
if size <= 2:
|
||||
clearScreen()
|
||||
print("Velikost hraciho pole (n*n):", size, "(upraveno na 3*3)")
|
||||
size = 3
|
||||
|
||||
|
||||
# prerequisite 03 -> allow a user to enter names of two players
|
||||
jmeno1 = input("Jmeno jednoho hrace: ")
|
||||
jmeno2 = input("Jmeno druheho hrace: ")
|
||||
|
||||
pole = []
|
||||
temp = []
|
||||
for i in range(size):
|
||||
for j in range(size):
|
||||
temp.append(' ')
|
||||
pole.append(temp)
|
||||
temp = []
|
||||
|
||||
while konec == 0:
|
||||
herniKolo(pole, jmeno1, jmeno2)
|
||||
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
|
||||
def vypisHru(pole, jmeno1, jmeno2):
|
||||
global error
|
||||
|
||||
if error == 1:
|
||||
print("Neplatna hodnota policka")
|
||||
error = 0
|
||||
print(jmeno1, "(o) vs", jmeno2, "(x)")
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
print(f"[{pole[i][j]}]", end=" ")
|
||||
print(" ")
|
||||
|
||||
def check(pole):
|
||||
# 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(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'o':
|
||||
o += 1
|
||||
if pole[i][j] == 'x':
|
||||
x += 1
|
||||
if o >= 3:
|
||||
return 0
|
||||
elif x >= 3:
|
||||
return 1
|
||||
|
||||
# vertical checking
|
||||
o = x = 0
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[j][i] == 'o':
|
||||
o += 1
|
||||
if pole[j][i] == 'x':
|
||||
x += 1
|
||||
if o >= 3:
|
||||
return 0
|
||||
elif x >= 3:
|
||||
return 1
|
||||
|
||||
# diagonal checking
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'o':
|
||||
# only 6 possibilities, so the program will try all of them
|
||||
try:
|
||||
if pole[i-1][j-1] == 'o' and pole[i-2][j-2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j+1] == 'o' and pole[i-2][j+2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i+1][j-1] == 'o' and pole[i+2][j-2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i+1][j+1] == 'o' and pole[i+2][j+2] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j-1] == 'o' and pole[i+1][j+1] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j+1] == 'o' and pole[i+1][j-1] == 'o':
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'x':
|
||||
try:
|
||||
if pole[i-1][j-1] == 'x' and pole[i-2][j-2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j+1] == 'x' and pole[i-2][j+2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i+1][j-1] == 'x' and pole[i+2][j-2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i+1][j+1] == 'x' and pole[i+2][j+2] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j-1] == 'x' and pole[i+1][j+1] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pole[i-1][j+1] == 'x' and pole[i+1][j-1] == 'x':
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
# draw checking
|
||||
# 2 is for when a draw occurs
|
||||
pocet = 0
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'o' or pole[i][j] == 'x':
|
||||
pocet += 1
|
||||
if pocet == len(pole)*len(pole):
|
||||
return 2
|
||||
|
||||
def herniKolo(pole, jmeno1, jmeno2):
|
||||
global konec, kdoHraje, error
|
||||
|
||||
# step 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# step 2 -> print the current state of the game
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
|
||||
# step 3 -> allow for one player or the other to insert coords
|
||||
rada = sloupec = None
|
||||
while rada == sloupec == None:
|
||||
try:
|
||||
rada, sloupec = map(int, input().split())
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
continue
|
||||
if rada <= 0 or sloupec <= 0:
|
||||
error = 1
|
||||
|
||||
# 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 kdoHraje 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
|
||||
try:
|
||||
if pole[rada-1][sloupec-1] == ' ' and 1 <= rada <= len(pole) and 1 <= sloupec <= len(pole):
|
||||
if kdoHraje == 0:
|
||||
pole[rada-1][sloupec-1] = 'o'
|
||||
kdoHraje = 1
|
||||
elif kdoHraje == 1:
|
||||
pole[rada-1][sloupec-1] = 'x'
|
||||
kdoHraje = 0
|
||||
except IndexError:
|
||||
error = 1
|
||||
|
||||
# step 5 -> check if the game should end (if someone won)
|
||||
vyherce = check(pole)
|
||||
|
||||
if vyherce == 0:
|
||||
# step 5.1 -> if yes -> end the game
|
||||
clearScreen()
|
||||
print("Vyhralo o!")
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
konec = 1
|
||||
# step 5.2 -> if no -> jump to step 1
|
||||
|
||||
if vyherce == 1:
|
||||
clearScreen()
|
||||
print("Vyhralo x!")
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
konec = 1
|
||||
|
||||
if vyherce == 2:
|
||||
clearScreen()
|
||||
print("Remiza!")
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
konec = 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
@@ -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()
|
||||
@@ -0,0 +1,284 @@
|
||||
# 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, pf
|
||||
|
||||
# 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 inBound(a, b, c, d):
|
||||
global pf
|
||||
|
||||
if len(pf) <= a >= 0 or len(pf) <= b >= 0 and len(pf) <= c >= 0 or len(pf) <= d >= 0:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
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' and inBound(i-1, j-1, i-2, j-2) == 1:
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'o' and pf[i-2][j+2] == 'o' and inBound(i-1, j+1, i-2, j+2) == 1:
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j-1] == 'o' and pf[i+2][j-2] == 'o' and inBound(i+1, j-1, i+2, j-2) == 1:
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j+1] == 'o' and pf[i+2][j+2] == 'o' and inBound(i+1, j+1, i+2, j+2) == 1:
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j-1] == 'o' and pf[i+1][j+1] == 'o' and inBound(i-1, j-1, i+1, j+1) == 1:
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'o' and pf[i+1][j-1] == 'o' and inBound(i-1, j+1, i+1, j-1) == 1:
|
||||
return 0
|
||||
except IndexError:
|
||||
continue
|
||||
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'x':
|
||||
# only 6 possibilities, so the program will try all of them
|
||||
try:
|
||||
if pf[i-1][j-1] == 'x' and pf[i-2][j-2] == 'x' and inBound(i-1, j-1, i-2, j-2) == 1:
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'x' and pf[i-2][j+2] == 'x' and inBound(i-1, j+1, i-2, j+2) == 1:
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j-1] == 'x' and pf[i+2][j-2] == 'x' and inBound(i+1, j-1, i+2, j-2) == 1:
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i+1][j+1] == 'x' and pf[i+2][j+2] == 'x' and inBound(i+1, j+1, i+2, j+2) == 1:
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j-1] == 'x' and pf[i+1][j+1] == 'x' and inBound(i-1, j-1, i+1, j+1) == 1:
|
||||
return 1
|
||||
except IndexError:
|
||||
continue
|
||||
try:
|
||||
if pf[i-1][j+1] == 'x' and pf[i+1][j-1] == 'x' and inBound(i-1, j+1, i+1, j-1) == 1:
|
||||
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()
|
||||
@@ -0,0 +1,179 @@
|
||||
# algorithm steps
|
||||
#
|
||||
# prerequisites
|
||||
# 01 allow a user to determine the size of the playfield
|
||||
# 02 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
|
||||
|
||||
konec = 0
|
||||
kdoHraje = 0
|
||||
def init():
|
||||
global konec, kdoHraje
|
||||
|
||||
# prerequisite 01 -> allow a user to determine the size of the playfield
|
||||
size = int(input())
|
||||
|
||||
# prerequisite 02 -> allow a user to enter names of two players
|
||||
jmeno1 = input()
|
||||
jmeno2 = input()
|
||||
|
||||
pole = []
|
||||
temp = []
|
||||
for i in range(size):
|
||||
for j in range(size):
|
||||
temp.append(' ')
|
||||
pole.append(temp)
|
||||
temp = []
|
||||
|
||||
while konec == 0:
|
||||
herniKolo(pole, jmeno1, jmeno2)
|
||||
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
|
||||
def vypisHru(pole, jmeno1, jmeno2):
|
||||
print(jmeno1, "(o) vs", jmeno2, "(x)")
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
print(f"[{pole[i][j]}]", end=" ")
|
||||
print(" ")
|
||||
|
||||
def check(pole):
|
||||
# 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(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'o':
|
||||
o += 1
|
||||
if pole[i][j] == 'x':
|
||||
x += 1
|
||||
if o >= 3:
|
||||
return 0
|
||||
elif x >= 3:
|
||||
return 1
|
||||
|
||||
# vertical checking
|
||||
o = x = 0
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[j][i] == 'o':
|
||||
o += 1
|
||||
if pole[j][i] == 'x':
|
||||
x += 1
|
||||
if o >= 3:
|
||||
return 0
|
||||
elif x >= 3:
|
||||
return 1
|
||||
|
||||
# diagonal checking
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'o':
|
||||
# only 6 possibilities, so the program will try all of them
|
||||
if pole[i-1][j-1] == 'o' and pole[i-2][j-2] == 'o':
|
||||
return 0
|
||||
if pole[i-1][j+1] == 'o' and pole[i-2][j+2] == 'o':
|
||||
return 0
|
||||
if pole[i+1][j-1] == 'o' and pole[i+2][j-2] == 'o':
|
||||
return 0
|
||||
if pole[i+1][j+1] == 'o' and pole[i+2][j+2] == 'o':
|
||||
return 0
|
||||
if pole[i-1][j-1] == 'o' and pole[i+1][j+1] == 'o':
|
||||
return 0
|
||||
if pole[i-1][j+1] == 'o' and pole[i+1][j-1] == 'o':
|
||||
return 0
|
||||
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'x':
|
||||
if pole[i-1][j-1] == 'x' and pole[i-2][j-2] == 'x':
|
||||
return 1
|
||||
if pole[i-1][j+1] == 'x' and pole[i-2][j+2] == 'x':
|
||||
return 1
|
||||
if pole[i+1][j-1] == 'x' and pole[i+2][j-2] == 'x':
|
||||
return 1
|
||||
if pole[i+1][j+1] == 'x' and pole[i+2][j+2] == 'x':
|
||||
return 1
|
||||
if pole[i-1][j-1] == 'x' and pole[i+1][j+1] == 'x':
|
||||
return 1
|
||||
if pole[i-1][j+1] == 'x' and pole[i+1][j-1] == 'x':
|
||||
return 1
|
||||
|
||||
# draw checking
|
||||
# 2 is for when a draw occurs
|
||||
pocet = 0
|
||||
for i in range(len(pole)):
|
||||
for j in range(len(pole)):
|
||||
if pole[i][j] == 'o' or pole[i][j] == 'x':
|
||||
pocet += 1
|
||||
if pocet == len(pole)*len(pole):
|
||||
return 2
|
||||
|
||||
def herniKolo(pole, jmeno1, jmeno2):
|
||||
global konec, kdoHraje
|
||||
|
||||
# step 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# step 2 -> print the current state of the game
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
|
||||
# step 3 -> allow for one player or the other to insert coords
|
||||
rada, sloupec = map(int, input().split())
|
||||
|
||||
# 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 kdoHraje 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 pole[rada-1][sloupec-1] == ' ' and 1 <= rada <= len(pole)-1 and 1 <= sloupec <= len(pole)-1:
|
||||
if kdoHraje == 0:
|
||||
pole[rada-1][sloupec-1] = 'o'
|
||||
kdoHraje = 1
|
||||
elif kdoHraje == 1:
|
||||
pole[rada-1][sloupec-1] = 'x'
|
||||
kdoHraje = 0
|
||||
|
||||
# step 5 -> check if the game should end (if someone won)
|
||||
vyherce = check(pole)
|
||||
|
||||
if vyherce == 0:
|
||||
# step 5.1 -> if yes -> end the game
|
||||
clearScreen()
|
||||
print("Vyhralo o!")
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
konec = 1
|
||||
# step 5.2 -> if no -> jump to step 1
|
||||
|
||||
if vyherce == 1:
|
||||
clearScreen()
|
||||
print("Vyhralo x!")
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
konec = 1
|
||||
|
||||
if vyherce == 2:
|
||||
clearScreen()
|
||||
print("Remiza!")
|
||||
vypisHru(pole, jmeno1, jmeno2)
|
||||
konec = 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
@@ -0,0 +1,452 @@
|
||||
# TODO -
|
||||
|
||||
# add:
|
||||
# fix: value exceptions
|
||||
# update:
|
||||
|
||||
# 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
|
||||
# 04 allow a user to determine the symbol count needed to win
|
||||
#
|
||||
# 1 clear the screen
|
||||
# 2 print the current state of the game
|
||||
# 3 allow for one player or the other to insert coords by moving with arrow keys and to put the symbol to the selected place by pressing space
|
||||
# 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, time
|
||||
from pynput import keyboard
|
||||
from pynput.keyboard import Key, Listener, KeyCode
|
||||
|
||||
# these global variables are flags
|
||||
end = 0
|
||||
turn = 0
|
||||
error = 0
|
||||
|
||||
# misc. global vars
|
||||
_size = 0
|
||||
winLine = []
|
||||
cursorX = cursorY = 0 # setting the default cursor position to the left top corner
|
||||
|
||||
# error codes
|
||||
#
|
||||
# 1 - invalid value
|
||||
# 2 - invalid index/position
|
||||
# 3 - index/position occupied
|
||||
|
||||
def init():
|
||||
global end, turn, pf, name1, name2, symbolCount, cursorX, cursorY, size, _size
|
||||
|
||||
# 01 -> clear the screen
|
||||
clearScreen()
|
||||
|
||||
# 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): "))
|
||||
_size = size
|
||||
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 < 3:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", size, "(changed to 3*3)")
|
||||
size = 3
|
||||
_size = size
|
||||
|
||||
|
||||
# 03 -> allow a user to enter names of two players
|
||||
name1 = input("Name of the first player: ")
|
||||
name2 = input("Name of the second player: ")
|
||||
|
||||
# 04 -> allow a user to determine the symbol count needed to win
|
||||
symbolCount = None
|
||||
F_printOneMoreTime = 0
|
||||
while symbolCount == None:
|
||||
try:
|
||||
symbolCount = int(input("Number of symbols inline needed to win: "))
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
print("Enter a number")
|
||||
F_printOneMoreTime = 1
|
||||
continue
|
||||
if F_printOneMoreTime == 1:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", size, "(changed to 3*3)")
|
||||
print("Name of the first player:", name1)
|
||||
print("Name of the second player:", name2)
|
||||
print("Number of symbols inline needed to win:", symbolCount)
|
||||
F_printOneMoreTime = 0
|
||||
if symbolCount > _size >= 0:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", _size)
|
||||
print("Name of the first player:", name1)
|
||||
print("Name of the second player:", name2)
|
||||
print("Number of symbols inline needed to win:", symbolCount, f"(changed to {_size}*{_size})")
|
||||
symbolCount = _size
|
||||
time.sleep(2)
|
||||
|
||||
# creating the playfield
|
||||
pf = [] # pf is shor for PlayField
|
||||
temp = []
|
||||
for i in range(size):
|
||||
for j in range(size):
|
||||
temp.append(' ')
|
||||
pf.append(temp)
|
||||
temp = []
|
||||
|
||||
# setting the hotkeys for moving with the cursor and putting down symbols
|
||||
|
||||
while end == 0:
|
||||
gameRound(pf, name1, name2)
|
||||
|
||||
# clears the screen
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
# detects if a position is inside the playfield
|
||||
def inBound(x):
|
||||
global _size
|
||||
|
||||
if 0 <= x < _size:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def blinkPrint(pf, name1, name2):
|
||||
clearScreen()
|
||||
print(name1, "(o) vs", name2, "(x)")
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if [i, j] in winLine:
|
||||
print("[ ]", end=" ")
|
||||
continue
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print("")
|
||||
time.sleep(0.5)
|
||||
|
||||
def _print(pf, name1, name2, blink = 0):
|
||||
clearScreen()
|
||||
if blink == 2:
|
||||
print("o won!")
|
||||
elif blink == 3:
|
||||
print("x won!")
|
||||
elif blink == 4:
|
||||
print("Draw!")
|
||||
|
||||
print(name1, "(o) vs", name2, "(x)")
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if cursorX == j and cursorY == i and blink == 0:
|
||||
print(f"#{pf[i][j]}#", end=" ")
|
||||
continue
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print("")
|
||||
if blink == 1:
|
||||
time.sleep(0.5)
|
||||
|
||||
# prints the current state of the game
|
||||
def gameState(pf, name1, name2, blink = 0):
|
||||
global error, cursorX, cursorY
|
||||
|
||||
if error == 1:
|
||||
print("Invalid value")
|
||||
error = 0
|
||||
if error == 2:
|
||||
print("Invalid position")
|
||||
error = 0
|
||||
if error == 3:
|
||||
print("Position occupied")
|
||||
error = 0
|
||||
|
||||
if blink == 1:
|
||||
for i in range(6):
|
||||
if i % 2 == 0:
|
||||
blinkPrint(pf, name1, name2)
|
||||
if i % 2 == 1:
|
||||
_print(pf, name1, name2, 1)
|
||||
elif blink == 0:
|
||||
_print(pf, name1, name2)
|
||||
elif blink == 2:
|
||||
_print(pf, name1, name2, 2)
|
||||
elif blink == 3:
|
||||
_print(pf, name1, name2, 3)
|
||||
elif blink == 4:
|
||||
_print(pf, name1, name2, 4)
|
||||
|
||||
# checks whether someone has won
|
||||
def check(pf):
|
||||
global symbolCount, winLine
|
||||
|
||||
winLine = []
|
||||
|
||||
# horizontal checking
|
||||
# 0 is for when 'o's win and 1 is for when 'x's win
|
||||
temp = []
|
||||
o = x = 0
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if pf[i][j] == 'o':
|
||||
temp.append([i, j])
|
||||
o += 1
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'x':
|
||||
temp = []
|
||||
o = 0
|
||||
if o < symbolCount:
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if pf[i][j] == 'x':
|
||||
temp.append([i, j])
|
||||
x += 1
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'o':
|
||||
temp = []
|
||||
x = 0
|
||||
if x < symbolCount:
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# vertical checking
|
||||
temp = []
|
||||
o = x = 0
|
||||
for j in range(_size):
|
||||
for i in range(_size):
|
||||
if pf[i][j] == 'o':
|
||||
temp.append([i, j])
|
||||
o += 1
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'x':
|
||||
temp = []
|
||||
o = 0
|
||||
if o < symbolCount:
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
for j in range(_size):
|
||||
for i in range(_size):
|
||||
if pf[i][j] == 'x':
|
||||
temp.append([i, j])
|
||||
x += 1
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'o':
|
||||
temp = []
|
||||
x = 0
|
||||
if x < symbolCount:
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# diagonal checking
|
||||
temp = []
|
||||
o = x = 0
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'o':
|
||||
try:
|
||||
if pf[i+1][j-1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'o' and 0 <= i+k < _size and 0 <= j-k < _size:
|
||||
temp.append([i+k, j-k])
|
||||
o += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
if pf[i+1][j+1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'o' and 0 <= i+k < _size and 0 <= j+k < _size:
|
||||
temp.append([i+k, j+k])
|
||||
o += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
except IndexError:
|
||||
pass
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
elif o < symbolCount:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
if pf[i][j] == 'x':
|
||||
try:
|
||||
if pf[i+1][j-1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'x' and 0 <= i+k < _size and 0 <= j-k < _size:
|
||||
temp.append([i+k, j-k])
|
||||
x += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
if pf[i+1][j+1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'x' and 0 <= i+k < _size and 0 <= j+k < _size:
|
||||
temp.append([i+k, j+k])
|
||||
x += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
except IndexError:
|
||||
pass
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
elif x < symbolCount:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# 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 cursorLeft():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX-1) == 1 and inBound(cursorY):
|
||||
cursorX -= 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorRight():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX+1) == 1 and inBound(cursorY) == 1:
|
||||
cursorX += 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorUp():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY-1) == 1:
|
||||
cursorY -= 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorDown():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY+1) == 1:
|
||||
cursorY += 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def putSymbol():
|
||||
global cursorX, cursorY, turn, pf, name1, name2
|
||||
|
||||
if turn == 0 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'o'
|
||||
turn = 1
|
||||
elif turn == 1 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'x'
|
||||
turn = 0
|
||||
clearScreen()
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def keys(key):
|
||||
global listener
|
||||
|
||||
if key == keyboard.Key.left:
|
||||
cursorLeft()
|
||||
if key == keyboard.Key.right:
|
||||
cursorRight()
|
||||
if key == keyboard.Key.up:
|
||||
cursorUp()
|
||||
if key == keyboard.Key.down:
|
||||
cursorDown()
|
||||
if key == keyboard.Key.space:
|
||||
listener.stop()
|
||||
putSymbol()
|
||||
|
||||
# logic for a round of the game
|
||||
def gameRound(pf, name1, name2):
|
||||
global end, turn, error, listener
|
||||
|
||||
# 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# 2 -> print the current state of the game
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
# 3 -> allow for one player or the other to move with arrow keys and to put the symbol to the selected place by pressing space
|
||||
#
|
||||
# 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
|
||||
with keyboard.Listener(
|
||||
on_press=keys,
|
||||
supress=True
|
||||
) as listener:
|
||||
listener.join()
|
||||
|
||||
# 5 -> check if the game should end (if someone won)
|
||||
won = check(pf)
|
||||
|
||||
if won == 0:
|
||||
# 5.1 -> if yes -> end the game
|
||||
gameState(pf, name1, name2, 1)
|
||||
gameState(pf, name1, name2, 2)
|
||||
end = 1
|
||||
# 5.2 -> if no -> jump to step 1
|
||||
|
||||
if won == 1:
|
||||
gameState(pf, name1, name2, 1)
|
||||
gameState(pf, name1, name2, 3)
|
||||
end = 1
|
||||
|
||||
if won == 2:
|
||||
gameState(pf, name1, name2, 4)
|
||||
end = 1
|
||||
|
||||
# driver code
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
@@ -0,0 +1,452 @@
|
||||
# TODO -
|
||||
|
||||
# add:
|
||||
# fix:
|
||||
# update:
|
||||
|
||||
# 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
|
||||
# 04 allow a user to determine the symbol count needed to win
|
||||
#
|
||||
# 1 clear the screen
|
||||
# 2 print the current state of the game
|
||||
# 3 allow for one player or the other to insert coords by moving with arrow keys and to put the symbol to the selected place by pressing space
|
||||
# 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, time
|
||||
from pynput import keyboard
|
||||
from pynput.keyboard import Key, Listener, KeyCode
|
||||
|
||||
# these global variables are flags
|
||||
end = 0
|
||||
turn = 0
|
||||
error = 0
|
||||
|
||||
# misc. global vars
|
||||
_size = 0
|
||||
winLine = []
|
||||
cursorX = cursorY = 0 # setting the default cursor position to the left top corner
|
||||
|
||||
# error codes
|
||||
#
|
||||
# 1 - invalid value
|
||||
# 2 - invalid index/position
|
||||
# 3 - index/position occupied
|
||||
|
||||
def init():
|
||||
global end, turn, pf, name1, name2, symbolCount, cursorX, cursorY, size, _size
|
||||
|
||||
# 01 -> clear the screen
|
||||
clearScreen()
|
||||
|
||||
# 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): "))
|
||||
_size = size
|
||||
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 < 3:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", size, "(changed to 3*3)")
|
||||
size = 3
|
||||
_size = size
|
||||
|
||||
|
||||
# 03 -> allow a user to enter names of two players
|
||||
name1 = input("Name of the first player: ")
|
||||
name2 = input("Name of the second player: ")
|
||||
|
||||
# 04 -> allow a user to determine the symbol count needed to win
|
||||
symbolCount = None
|
||||
F_printOneMoreTime = 0
|
||||
while symbolCount == None:
|
||||
try:
|
||||
symbolCount = int(input("Number of symbols inline needed to win: "))
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
print("Enter a number")
|
||||
F_printOneMoreTime = 1
|
||||
continue
|
||||
if F_printOneMoreTime == 1:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", size, "(changed to 3*3)")
|
||||
print("Name of the first player:", name1)
|
||||
print("Name of the second player:", name2)
|
||||
print("Number of symbols inline needed to win:", symbolCount)
|
||||
F_printOneMoreTime = 0
|
||||
if symbolCount > _size >= 0:
|
||||
clearScreen()
|
||||
print("Size of the playfield (n*n):", _size)
|
||||
print("Name of the first player:", name1)
|
||||
print("Name of the second player:", name2)
|
||||
print("Number of symbols inline needed to win:", symbolCount, f"(changed to {_size}*{_size})")
|
||||
symbolCount = _size
|
||||
time.sleep(2)
|
||||
|
||||
# creating the playfield
|
||||
pf = [] # pf is shor for PlayField
|
||||
temp = []
|
||||
for i in range(size):
|
||||
for j in range(size):
|
||||
temp.append(' ')
|
||||
pf.append(temp)
|
||||
temp = []
|
||||
|
||||
# setting the hotkeys for moving with the cursor and putting down symbols
|
||||
|
||||
while end == 0:
|
||||
gameRound(pf, name1, name2)
|
||||
|
||||
# clears the screen
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
# detects if a position is inside the playfield
|
||||
def inBound(x):
|
||||
global _size
|
||||
|
||||
if 0 <= x < _size:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def blinkPrint(pf, name1, name2):
|
||||
clearScreen()
|
||||
print(name1, "(o) vs", name2, "(x)")
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if [i, j] in winLine:
|
||||
print("[ ]", end=" ")
|
||||
continue
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print("")
|
||||
time.sleep(0.5)
|
||||
|
||||
def _print(pf, name1, name2, blink = 0):
|
||||
clearScreen()
|
||||
if blink == 2:
|
||||
print("o won!")
|
||||
elif blink == 3:
|
||||
print("x won!")
|
||||
elif blink == 4:
|
||||
print("Draw!")
|
||||
|
||||
print(name1, "(o) vs", name2, "(x)")
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if cursorX == j and cursorY == i and blink == 0:
|
||||
print(f"#{pf[i][j]}#", end=" ")
|
||||
continue
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print("")
|
||||
if blink == 1:
|
||||
time.sleep(0.5)
|
||||
|
||||
# prints the current state of the game
|
||||
def gameState(pf, name1, name2, blink = 0):
|
||||
global error, cursorX, cursorY
|
||||
|
||||
if error == 1:
|
||||
print("Invalid value")
|
||||
error = 0
|
||||
if error == 2:
|
||||
print("Invalid position")
|
||||
error = 0
|
||||
if error == 3:
|
||||
print("Position occupied")
|
||||
error = 0
|
||||
|
||||
if blink == 1:
|
||||
for i in range(6):
|
||||
if i % 2 == 0:
|
||||
blinkPrint(pf, name1, name2)
|
||||
if i % 2 == 1:
|
||||
_print(pf, name1, name2, 1)
|
||||
elif blink == 0:
|
||||
_print(pf, name1, name2)
|
||||
elif blink == 2:
|
||||
_print(pf, name1, name2, 2)
|
||||
elif blink == 3:
|
||||
_print(pf, name1, name2, 3)
|
||||
elif blink == 4:
|
||||
_print(pf, name1, name2, 4)
|
||||
|
||||
# checks whether someone has won
|
||||
def check(pf):
|
||||
global symbolCount, winLine
|
||||
|
||||
winLine = []
|
||||
|
||||
# horizontal checking
|
||||
# 0 is for when 'o's win and 1 is for when 'x's win
|
||||
temp = []
|
||||
o = x = 0
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if pf[i][j] == 'o':
|
||||
temp.append([i, j])
|
||||
o += 1
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'x':
|
||||
temp = []
|
||||
o = 0
|
||||
if o < symbolCount:
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if pf[i][j] == 'x':
|
||||
temp.append([i, j])
|
||||
x += 1
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'o':
|
||||
temp = []
|
||||
x = 0
|
||||
if x < symbolCount:
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# vertical checking
|
||||
temp = []
|
||||
o = x = 0
|
||||
for j in range(_size):
|
||||
for i in range(_size):
|
||||
if pf[i][j] == 'o':
|
||||
temp.append([i, j])
|
||||
o += 1
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'x':
|
||||
temp = []
|
||||
o = 0
|
||||
if o < symbolCount:
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
for j in range(_size):
|
||||
for i in range(_size):
|
||||
if pf[i][j] == 'x':
|
||||
temp.append([i, j])
|
||||
x += 1
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'o':
|
||||
temp = []
|
||||
x = 0
|
||||
if x < symbolCount:
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# diagonal checking
|
||||
temp = []
|
||||
o = x = 0
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'o':
|
||||
try:
|
||||
if pf[i+1][j-1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'o' and 0 <= i+k < _size and 0 <= j-k < _size:
|
||||
temp.append([i+k, j-k])
|
||||
o += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
if pf[i+1][j+1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'o' and 0 <= i+k < _size and 0 <= j+k < _size:
|
||||
temp.append([i+k, j+k])
|
||||
o += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
except IndexError:
|
||||
pass
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
elif o < symbolCount:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
if pf[i][j] == 'x':
|
||||
try:
|
||||
if pf[i+1][j-1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'x' and 0 <= i+k < _size and 0 <= j-k < _size:
|
||||
temp.append([i+k, j-k])
|
||||
x += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
if pf[i+1][j+1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'x' and 0 <= i+k < _size and 0 <= j+k < _size:
|
||||
temp.append([i+k, j+k])
|
||||
x += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
except IndexError:
|
||||
pass
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
elif x < symbolCount:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# 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 cursorLeft():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX-1) == 1 and inBound(cursorY):
|
||||
cursorX -= 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorRight():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX+1) == 1 and inBound(cursorY) == 1:
|
||||
cursorX += 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorUp():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY-1) == 1:
|
||||
cursorY -= 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorDown():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY+1) == 1:
|
||||
cursorY += 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def putSymbol():
|
||||
global cursorX, cursorY, turn, pf, name1, name2
|
||||
|
||||
if turn == 0 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'o'
|
||||
turn = 1
|
||||
elif turn == 1 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'x'
|
||||
turn = 0
|
||||
clearScreen()
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def keys(key):
|
||||
global listener
|
||||
|
||||
if key == keyboard.Key.left:
|
||||
cursorLeft()
|
||||
if key == keyboard.Key.right:
|
||||
cursorRight()
|
||||
if key == keyboard.Key.up:
|
||||
cursorUp()
|
||||
if key == keyboard.Key.down:
|
||||
cursorDown()
|
||||
if key == keyboard.Key.space:
|
||||
listener.stop()
|
||||
putSymbol()
|
||||
|
||||
# logic for a round of the game
|
||||
def gameRound(pf, name1, name2):
|
||||
global end, turn, error, listener
|
||||
|
||||
# 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# 2 -> print the current state of the game
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
# 3 -> allow for one player or the other to move with arrow keys and to put the symbol to the selected place by pressing space
|
||||
#
|
||||
# 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
|
||||
with keyboard.Listener(
|
||||
on_press=keys,
|
||||
supress=True
|
||||
) as listener:
|
||||
listener.join()
|
||||
|
||||
# 5 -> check if the game should end (if someone won)
|
||||
won = check(pf)
|
||||
|
||||
if won == 0:
|
||||
# 5.1 -> if yes -> end the game
|
||||
gameState(pf, name1, name2, 1)
|
||||
gameState(pf, name1, name2, 2)
|
||||
end = 1
|
||||
# 5.2 -> if no -> jump to step 1
|
||||
|
||||
if won == 1:
|
||||
gameState(pf, name1, name2, 1)
|
||||
gameState(pf, name1, name2, 3)
|
||||
end = 1
|
||||
|
||||
if won == 2:
|
||||
gameState(pf, name1, name2, 4)
|
||||
end = 1
|
||||
|
||||
# driver code
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
@@ -0,0 +1,440 @@
|
||||
# TODO -
|
||||
|
||||
# add:
|
||||
# fix:
|
||||
# update:
|
||||
|
||||
# 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
|
||||
# 04 allow a user to determine the symbol count needed to win
|
||||
#
|
||||
# 1 clear the screen
|
||||
# 2 print the current state of the game
|
||||
# 3 allow for one player or the other to insert coords by moving with arrow keys and to put the symbol to the selected place by pressing space
|
||||
# 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, time
|
||||
from pynput import keyboard
|
||||
from pynput.keyboard import Key, Listener, KeyCode
|
||||
|
||||
# these global variables are flags
|
||||
end = 0
|
||||
turn = 0
|
||||
error = 0
|
||||
|
||||
# misc. global vars
|
||||
_size = 0
|
||||
winLine = []
|
||||
cursorX = cursorY = 0 # setting the default cursor position to the left top corner
|
||||
|
||||
# error codes
|
||||
#
|
||||
# 1 - invalid value
|
||||
# 2 - invalid index/position
|
||||
# 3 - index/position occupied
|
||||
|
||||
def init():
|
||||
global end, turn, pf, name1, name2, symbolCount, cursorX, cursorY, size, _size
|
||||
|
||||
# 01 -> clear the screen
|
||||
clearScreen()
|
||||
|
||||
# 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): "))
|
||||
_size = size
|
||||
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
|
||||
|
||||
|
||||
# 03 -> allow a user to enter names of two players
|
||||
name1 = input("Name of the first player: ")
|
||||
name2 = input("Name of the second player: ")
|
||||
|
||||
# 04 -> allow a user to determine the symbol count needed to win
|
||||
symbolCount = None
|
||||
F_printOneMoreTime = 0
|
||||
while symbolCount == None:
|
||||
try:
|
||||
symbolCount = int(input("Number of symbols inline needed to win: "))
|
||||
except ValueError:
|
||||
clearScreen()
|
||||
print("Enter a number")
|
||||
F_printOneMoreTime = 1
|
||||
continue
|
||||
if F_printOneMoreTime == 1:
|
||||
clearScreen()
|
||||
print("Number of symbols inline needed to win:", symbolCount)
|
||||
F_printOneMoreTime = 0
|
||||
|
||||
# creating the playfield
|
||||
pf = [] # pf is shor for PlayField
|
||||
temp = []
|
||||
for i in range(size):
|
||||
for j in range(size):
|
||||
temp.append(' ')
|
||||
pf.append(temp)
|
||||
temp = []
|
||||
|
||||
# setting the hotkeys for moving with the cursor and putting down symbols
|
||||
|
||||
while end == 0:
|
||||
gameRound(pf, name1, name2)
|
||||
|
||||
# clears the screen
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
# detects if a position is inside the playfield
|
||||
def inBound(x):
|
||||
global _size
|
||||
|
||||
if 0 <= x < _size:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def blinkPrint(pf, name1, name2):
|
||||
clearScreen()
|
||||
print(name1, "(o) vs", name2, "(x)")
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if [i, j] in winLine:
|
||||
print("[ ]", end=" ")
|
||||
continue
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print("")
|
||||
time.sleep(0.5)
|
||||
|
||||
def _print(pf, name1, name2, blink = 0):
|
||||
clearScreen()
|
||||
if blink == 2:
|
||||
print("o won!")
|
||||
elif blink == 3:
|
||||
print("x won!")
|
||||
elif blink == 4:
|
||||
print("Draw!")
|
||||
|
||||
print(name1, "(o) vs", name2, "(x)")
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if cursorX == j and cursorY == i and blink == 0:
|
||||
print(f"#{pf[i][j]}#", end=" ")
|
||||
continue
|
||||
print(f"[{pf[i][j]}]", end=" ")
|
||||
print("")
|
||||
if blink == 1:
|
||||
time.sleep(0.5)
|
||||
|
||||
# prints the current state of the game
|
||||
def gameState(pf, name1, name2, blink = 0):
|
||||
global error, cursorX, cursorY
|
||||
|
||||
if error == 1:
|
||||
print("Invalid value")
|
||||
error = 0
|
||||
if error == 2:
|
||||
print("Invalid position")
|
||||
error = 0
|
||||
if error == 3:
|
||||
print("Position occupied")
|
||||
error = 0
|
||||
|
||||
if blink == 1:
|
||||
for i in range(6):
|
||||
if i % 2 == 0:
|
||||
blinkPrint(pf, name1, name2)
|
||||
if i % 2 == 1:
|
||||
_print(pf, name1, name2, 1)
|
||||
elif blink == 0:
|
||||
_print(pf, name1, name2)
|
||||
elif blink == 2:
|
||||
_print(pf, name1, name2, 2)
|
||||
elif blink == 3:
|
||||
_print(pf, name1, name2, 3)
|
||||
elif blink == 4:
|
||||
_print(pf, name1, name2, 4)
|
||||
|
||||
# checks whether someone has won
|
||||
def check(pf):
|
||||
global symbolCount, winLine
|
||||
|
||||
winLine = []
|
||||
|
||||
# horizontal checking
|
||||
# 0 is for when 'o's win and 1 is for when 'x's win
|
||||
temp = []
|
||||
o = x = 0
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if pf[i][j] == 'o':
|
||||
temp.append([i, j])
|
||||
o += 1
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'x':
|
||||
temp = []
|
||||
o = 0
|
||||
if o < symbolCount:
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
for i in range(_size):
|
||||
for j in range(_size):
|
||||
if pf[i][j] == 'x':
|
||||
temp.append([i, j])
|
||||
x += 1
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'o':
|
||||
temp = []
|
||||
x = 0
|
||||
if x < symbolCount:
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# vertical checking
|
||||
temp = []
|
||||
o = x = 0
|
||||
for j in range(_size):
|
||||
for i in range(_size):
|
||||
if pf[i][j] == 'o':
|
||||
temp.append([i, j])
|
||||
o += 1
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'x':
|
||||
temp = []
|
||||
o = 0
|
||||
if o < symbolCount:
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
for j in range(_size):
|
||||
for i in range(_size):
|
||||
if pf[i][j] == 'x':
|
||||
temp.append([i, j])
|
||||
x += 1
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
if pf[i][j] == ' ' or pf[i][j] == 'o':
|
||||
temp = []
|
||||
x = 0
|
||||
if x < symbolCount:
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# diagonal checking
|
||||
temp = []
|
||||
o = x = 0
|
||||
for i in range(len(pf)):
|
||||
for j in range(len(pf)):
|
||||
if pf[i][j] == 'o':
|
||||
try:
|
||||
if pf[i+1][j-1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'o' and 0 <= i+k < _size and 0 <= j-k < _size:
|
||||
temp.append([i+k, j-k])
|
||||
o += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
if pf[i+1][j+1] == 'o':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'o' and 0 <= i+k < _size and 0 <= j+k < _size:
|
||||
temp.append([i+k, j+k])
|
||||
o += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
except IndexError:
|
||||
pass
|
||||
if o == symbolCount:
|
||||
winLine = temp
|
||||
return 0
|
||||
elif o < symbolCount:
|
||||
winLine = []
|
||||
temp = []
|
||||
o = 0
|
||||
|
||||
if pf[i][j] == 'x':
|
||||
try:
|
||||
if pf[i+1][j-1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j-k] == 'x' and 0 <= i+k < _size and 0 <= j-k < _size:
|
||||
temp.append([i+k, j-k])
|
||||
x += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
except IndexError:
|
||||
pass
|
||||
try:
|
||||
if pf[i+1][j+1] == 'x':
|
||||
for k in range(symbolCount):
|
||||
if pf[i+k][j+k] == 'x' and 0 <= i+k < _size and 0 <= j+k < _size:
|
||||
temp.append([i+k, j+k])
|
||||
x += 1
|
||||
else:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
except IndexError:
|
||||
pass
|
||||
if x == symbolCount:
|
||||
winLine = temp
|
||||
return 1
|
||||
elif x < symbolCount:
|
||||
winLine = []
|
||||
temp = []
|
||||
x = 0
|
||||
|
||||
# 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 cursorLeft():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX-1) == 1 and inBound(cursorY):
|
||||
cursorX -= 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorRight():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX+1) == 1 and inBound(cursorY) == 1:
|
||||
cursorX += 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorUp():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY-1) == 1:
|
||||
cursorY -= 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def cursorDown():
|
||||
global cursorX, cursorY, pf, name1, name2, error
|
||||
|
||||
if inBound(cursorX) == 1 and inBound(cursorY+1) == 1:
|
||||
cursorY += 1
|
||||
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def putSymbol():
|
||||
global cursorX, cursorY, turn, pf, name1, name2
|
||||
|
||||
if turn == 0 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'o'
|
||||
turn = 1
|
||||
elif turn == 1 and pf[cursorY][cursorX] == ' ':
|
||||
pf[cursorY][cursorX] = 'x'
|
||||
turn = 0
|
||||
clearScreen()
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
def keys(key):
|
||||
global listener
|
||||
|
||||
if key == keyboard.Key.left:
|
||||
cursorLeft()
|
||||
if key == keyboard.Key.right:
|
||||
cursorRight()
|
||||
if key == keyboard.Key.up:
|
||||
cursorUp()
|
||||
if key == keyboard.Key.down:
|
||||
cursorDown()
|
||||
if key == keyboard.Key.space:
|
||||
listener.stop()
|
||||
putSymbol()
|
||||
|
||||
# logic for a round of the game
|
||||
def gameRound(pf, name1, name2):
|
||||
global end, turn, error, listener
|
||||
|
||||
# 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# 2 -> print the current state of the game
|
||||
gameState(pf, name1, name2)
|
||||
|
||||
# 3 -> allow for one player or the other to move with arrow keys and to put the symbol to the selected place by pressing space
|
||||
#
|
||||
# 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
|
||||
with keyboard.Listener(
|
||||
on_press=keys,
|
||||
supress=True
|
||||
) as listener:
|
||||
listener.join()
|
||||
|
||||
# 5 -> check if the game should end (if someone won)
|
||||
won = check(pf)
|
||||
|
||||
if won == 0:
|
||||
# 5.1 -> if yes -> end the game
|
||||
gameState(pf, name1, name2, 1)
|
||||
gameState(pf, name1, name2, 2)
|
||||
end = 1
|
||||
# 5.2 -> if no -> jump to step 1
|
||||
|
||||
if won == 1:
|
||||
gameState(pf, name1, name2, 1)
|
||||
gameState(pf, name1, name2, 3)
|
||||
end = 1
|
||||
|
||||
if won == 2:
|
||||
gameState(pf, name1, name2, 4)
|
||||
end = 1
|
||||
|
||||
# driver code
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
import os
|
||||
|
||||
konec = 0
|
||||
kdoHraje = 0
|
||||
def init():
|
||||
global konec, kdoHraje
|
||||
|
||||
pole = [[' ', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
|
||||
|
||||
while konec == 0:
|
||||
herniKolo(pole)
|
||||
|
||||
def clearScreen():
|
||||
if os.name == "posix":
|
||||
os.system("clear")
|
||||
if os.name == "nt":
|
||||
os.system("cls")
|
||||
|
||||
|
||||
def vypisHru(pole):
|
||||
for i in range(3):
|
||||
print(f"[{pole[i][0]}] [{pole[i][1]}] [{pole[i][2]}]")
|
||||
|
||||
def check(pole):
|
||||
# horizontal checking
|
||||
# 0 is for when 'o's win and 1 is for when 'x's win
|
||||
for i in range(3):
|
||||
if pole[i][0] == pole[i][1] == pole[i][2] == 'o':
|
||||
return 0
|
||||
if pole[i][0] == pole[i][1] == pole[i][2] == 'x':
|
||||
return 1
|
||||
|
||||
# vertical checking
|
||||
for i in range(3):
|
||||
if pole[0][i] == pole[1][i] == pole[2][i] == 'o':
|
||||
return 0
|
||||
if pole[0][i] == pole[1][i] == pole[2][i] == 'x':
|
||||
return 1
|
||||
|
||||
# diagonal checking
|
||||
if pole[0][0] == pole[1][1] == pole[2][2] == 'o':
|
||||
return 0
|
||||
if pole[0][0] == pole[1][1] == pole[2][2] == 'x':
|
||||
return 1
|
||||
if pole[0][2] == pole[1][1] == pole[2][0] == 'o':
|
||||
return 0
|
||||
if pole[0][2] == pole[1][1] == pole[2][0] == 'x':
|
||||
return 1
|
||||
|
||||
# draw checking
|
||||
# 2 is for when a draw occurs
|
||||
pocet = 0
|
||||
for i in range(3):
|
||||
for j in range(3):
|
||||
if pole[i][j] == 'o' or pole[i][j] == 'x':
|
||||
pocet += 1
|
||||
if pocet == 9:
|
||||
return 2
|
||||
|
||||
def herniKolo(pole):
|
||||
global konec, kdoHraje
|
||||
|
||||
# algorithm steps
|
||||
#
|
||||
# 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
|
||||
|
||||
# step 1 -> clear the screen
|
||||
#
|
||||
# cross-platform (Windows, Unix-like OSs)
|
||||
clearScreen()
|
||||
|
||||
# step 2 -> print the current state of the game
|
||||
vypisHru(pole)
|
||||
|
||||
# step 3 -> allow for one player or the other to insert coords
|
||||
rada, sloupec = map(int, input().split())
|
||||
|
||||
# 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 kdoHraje 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 pole[rada-1][sloupec-1] == ' ' and 1 <= rada <= 3 and 1 <= sloupec <= 3:
|
||||
print(kdoHraje)
|
||||
if kdoHraje == 0:
|
||||
pole[rada-1][sloupec-1] = 'o'
|
||||
kdoHraje = 1
|
||||
elif kdoHraje == 1:
|
||||
pole[rada-1][sloupec-1] = 'x'
|
||||
kdoHraje = 0
|
||||
|
||||
# step 5 -> check if the game should end (if someone won)
|
||||
vyherce = check(pole)
|
||||
|
||||
if vyherce == 0:
|
||||
# step 5.1 -> if yes -> end the game
|
||||
clearScreen()
|
||||
print("Vyhralo o!")
|
||||
vypisHru(pole)
|
||||
konec = 1
|
||||
# step 5.2 -> if no -> jump to step 1
|
||||
|
||||
if vyherce == 1:
|
||||
clearScreen()
|
||||
print("Vyhralo x!")
|
||||
vypisHru(pole)
|
||||
konec = 1
|
||||
|
||||
if vyherce == 2:
|
||||
clearScreen()
|
||||
print("Remiza!")
|
||||
vypisHru(pole)
|
||||
konec = 1
|
||||
|
||||
if __name__ == "__main__":
|
||||
init()
|
||||
Reference in New Issue
Block a user