From d7835c88788f746ada2f963b90ba2f6b259e99fe Mon Sep 17 00:00:00 2001 From: mnjx Date: Sun, 5 Mar 2023 22:51:59 -1000 Subject: [PATCH] late commit; add: general bugfixes --- latest/tictactoe-latest.py | 42 +-- ...actoe-v2.1.3-new.py => tictactoe-v2.1.3.py | 0 tictactoe-v2.1.4-new.py | 284 ++++++++++++++++++ 3 files changed, 309 insertions(+), 17 deletions(-) rename tictactoe-v2.1.3-new.py => tictactoe-v2.1.3.py (100%) create mode 100644 tictactoe-v2.1.4-new.py diff --git a/latest/tictactoe-latest.py b/latest/tictactoe-latest.py index 79cf8c1..4c9a111 100644 --- a/latest/tictactoe-latest.py +++ b/latest/tictactoe-latest.py @@ -27,7 +27,7 @@ error = 0 # 3 - index/position occupied def init(): - global end, turn + global end, turn, pf # prerequisite 01 -> clear the screen clearScreen() @@ -74,6 +74,13 @@ def clearScreen(): 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 @@ -103,9 +110,9 @@ def check(pf): o += 1 if pf[i][j] == 'x': x += 1 - if o >= 3: + if o == 3: return 0 - elif x >= 3: + elif x == 3: return 1 if o < 3 or x < 3: o = x = 0 @@ -118,9 +125,9 @@ def check(pf): o += 1 if pf[j][i] == 'x': x += 1 - if o >= 3: + if o == 3: return 0 - elif x >= 3: + elif x == 3: return 1 if o < 3 or x < 3: o = x = 0 @@ -131,32 +138,32 @@ def check(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': + 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': + 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': + 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': + 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': + 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': + 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 @@ -164,33 +171,34 @@ def check(pf): 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': + 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': + 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': + 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': + 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': + 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': + 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 diff --git a/tictactoe-v2.1.3-new.py b/tictactoe-v2.1.3.py similarity index 100% rename from tictactoe-v2.1.3-new.py rename to tictactoe-v2.1.3.py diff --git a/tictactoe-v2.1.4-new.py b/tictactoe-v2.1.4-new.py new file mode 100644 index 0000000..4c9a111 --- /dev/null +++ b/tictactoe-v2.1.4-new.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