diff --git a/README.md b/README.md new file mode 100644 index 0000000..4ad7ded --- /dev/null +++ b/README.md @@ -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. \ No newline at end of file diff --git a/baks/tictactoe-v2.2-cursor.py.bak b/baks/tictactoe-v2.2-cursor.py.bak new file mode 100644 index 0000000..61f9467 --- /dev/null +++ b/baks/tictactoe-v2.2-cursor.py.bak @@ -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() \ No newline at end of file diff --git a/baks/tictactoe-v2.2-var-sym-count.py.bak b/baks/tictactoe-v2.2-var-sym-count.py.bak new file mode 100644 index 0000000..b542276 --- /dev/null +++ b/baks/tictactoe-v2.2-var-sym-count.py.bak @@ -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() \ No newline at end of file diff --git a/latest/tictactoe-latest.py b/latest/tictactoe-latest.py new file mode 100644 index 0000000..9926dad --- /dev/null +++ b/latest/tictactoe-latest.py @@ -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() \ No newline at end of file diff --git a/launch.sh b/launch.sh new file mode 100644 index 0000000..ccacb3e --- /dev/null +++ b/launch.sh @@ -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 diff --git a/tictactoe-v2.1.1.py b/tictactoe-v2.1.1.py new file mode 100644 index 0000000..9d4156a --- /dev/null +++ b/tictactoe-v2.1.1.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() \ No newline at end of file diff --git a/tictactoe-v2.1.2.py b/tictactoe-v2.1.2.py new file mode 100644 index 0000000..82a9d44 --- /dev/null +++ b/tictactoe-v2.1.2.py @@ -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() \ No newline at end of file diff --git a/tictactoe-v2.1.3.py b/tictactoe-v2.1.3.py new file mode 100644 index 0000000..79cf8c1 --- /dev/null +++ b/tictactoe-v2.1.3.py @@ -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() \ No newline at end of file diff --git a/tictactoe-v2.1.4.py b/tictactoe-v2.1.4.py new file mode 100644 index 0000000..4c9a111 --- /dev/null +++ b/tictactoe-v2.1.4.py @@ -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() \ No newline at end of file diff --git a/tictactoe-v2.1.py b/tictactoe-v2.1.py new file mode 100644 index 0000000..8891b88 --- /dev/null +++ b/tictactoe-v2.1.py @@ -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() \ No newline at end of file diff --git a/tictactoe-v2.2.1.py b/tictactoe-v2.2.1.py new file mode 100644 index 0000000..989a8a9 --- /dev/null +++ b/tictactoe-v2.2.1.py @@ -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() \ No newline at end of file diff --git a/tictactoe-v2.2.2-new.py b/tictactoe-v2.2.2-new.py new file mode 100644 index 0000000..9926dad --- /dev/null +++ b/tictactoe-v2.2.2-new.py @@ -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() \ No newline at end of file diff --git a/tictactoe-v2.2.py b/tictactoe-v2.2.py new file mode 100644 index 0000000..6abf830 --- /dev/null +++ b/tictactoe-v2.2.py @@ -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() \ No newline at end of file diff --git a/tictactoe-v2.py b/tictactoe-v2.py new file mode 100644 index 0000000..efb3e86 --- /dev/null +++ b/tictactoe-v2.py @@ -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() \ No newline at end of file