add: README.md file; fix: end-user improvements, general bugfixes
This commit is contained in:
@@ -0,0 +1,27 @@
|
|||||||
|
# TicTacToe
|
||||||
|
|
||||||
|
A simple CLI TicTacToe-like game written in Python
|
||||||
|
Latest version - v2.1.2
|
||||||
|
|
||||||
|
## Key features
|
||||||
|
|
||||||
|
+ Variable playfield size
|
||||||
|
+ Ability to insert player names
|
||||||
|
|
||||||
|
## Gameplay
|
||||||
|
|
||||||
|
Upon startup, you are prompted to enter the playfield size, for
|
||||||
|
example: you enter `3`, so the playfield area will be 3 rows high
|
||||||
|
and 3 columns wide. Then you enter the name of player one and
|
||||||
|
player two. The first player always begins. 3 by 3 is the smallest
|
||||||
|
possible playfield area size.
|
||||||
|
|
||||||
|
When the game itself starts, you are prompted to enter the coordinates
|
||||||
|
of the field you want your symbol to go into. For example: if your
|
||||||
|
symbol is 'o' and you enter `1 1`, then an 'o' will be placed in the
|
||||||
|
top left corner of the playfield area.
|
||||||
|
|
||||||
|
A game ends, when one player or the other has placed 3 of their symbols
|
||||||
|
in either a horizontal row, a vertical row, or a diagonal row. There
|
||||||
|
can also be a draw, that is, when none of the players have managed
|
||||||
|
to place 3 of their symbols in a row.
|
||||||
@@ -0,0 +1,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()
|
||||||
Reference in New Issue
Block a user