Compare commits

...

24 Commits

Author SHA1 Message Date
oto
71e0247304 Began working on the interface 2022-08-17 14:53:32 +03:00
oto
93403cdf83 Put interface into a separate file 2022-08-17 14:53:23 +03:00
oto
a2e0504aa8 Create Constants.py 2022-08-17 14:25:56 +03:00
oto
69ce05886d did some formatting 2022-08-17 12:38:04 +03:00
oto
e53fd7236c Added a timer 2022-08-15 07:31:52 +03:00
oto
cb8036bc6d Removed an excessive method
There's no main loop for this game, bruh. Why I put it here?..
2022-08-15 07:30:21 +03:00
oto
00da6deb24 Removed shared score var
A design flaw, makes no sense.
2022-08-15 07:29:50 +03:00
oto
00daf53fae soft internalized some methods
Have learned how to "internalize" methods 😆
2022-08-15 07:29:25 +03:00
oto
446ffba554 Pulled out code into Timer.py
Made a separate class instead of keeping it in GameLogic.
2022-08-15 07:28:17 +03:00
oto
9c9db7aba9 PEP Compliance edit 2022-08-15 07:26:45 +03:00
oto
7b486881d9 Create Timer.py
Pulled it out of GameLogic class. Makes sense to keep it separate.
2022-08-15 07:26:15 +03:00
oto
b11f77f7ef Update tester.py 2022-08-15 07:25:39 +03:00
oto
54a0f42137 Added score counting
It makes no sense to keep one score for everyone, in GameMap. A design flaw.
2022-08-15 07:25:25 +03:00
oto
d329c0f7ab exposing my test suite. for u. to see. 2022-08-07 09:33:07 +03:00
oto
8bc369c31c a little reminder to myself 2022-08-07 09:32:16 +03:00
oto
e8236a7e4a made it remember its marks 2022-08-07 09:26:57 +03:00
oto
468237429e Switched to TKinter
Switched since the game has no mainloop, and only works when you commit an action. It makes sense, ye know. Maybe when i'll get some better graphics i'll switch to another lib, but for now, I'll use TKinter.
2022-08-07 09:26:13 +03:00
oto
ab37e797de elaborated a moment 2022-08-07 09:24:40 +03:00
oto
344f2e2909 added brackets to the player name 2022-08-07 09:24:27 +03:00
oto
bc3d3b59c9 Explained some stuff 2022-08-07 09:24:05 +03:00
oto
855e53befe Fixed a syntax error 2022-08-07 09:23:52 +03:00
oto
8dd2035167 Added win condition logic
It was the hardest to implement, but yay, I did it.
2022-08-07 09:23:10 +03:00
oto
a9b8409928 removed an excessive space 2022-08-07 09:22:16 +03:00
oto
5b74ecef52 Added default rules
Same as in regular classic TicTacToe.
2022-08-07 09:22:06 +03:00
9 changed files with 130 additions and 33 deletions

2
.gitignore vendored
View File

@ -1,2 +0,0 @@
tester.py

1
Constants.py Normal file
View File

@ -0,0 +1 @@
VERSION_NUMBER = "0.1"

View File

@ -1,36 +1,39 @@
from datetime import datetime, time
from GameMap import *
from Player import *
from Timer import *
class GameLogic():
def __init__(self, gameMap, playerList, winRowLength, individualMoves):
def __init__(self, gameMap, playerList, winRowLength=3, individualMoves=1):
self.gameMap = gameMap
self.playerList = playerList
self.winRowLength = winRowLength
self.individualMoves = individualMoves
self.score = 0
self.wait_for_input()
self.timer = Timer()
def check_who_win(self):
# Should have used vectors instead of committing tuples mithosis,
# but whatever, it works anyway, and if it works, why code more
# for nothing?
for player in self.playerList:
markList = player.get_markList()
# since every mark is checked, there's no need to go into
# opposite directions, so, there is (0,1) but no (0, -1).
# This twice decreases the amount of computation needed.
# maybe TODO - Optimize even more by preventing repeated calculations.
directions = ((0, 1), (1, 0), (1,1), (-1, 1))
for mark in markList:
for direction in directions:
if self._is_line(markList, mark, direction):
return player
return False
def wait_for_input(self):
pass
def check_for_win(self, playerList):
for player in playerList:
pass
def get_time(self):
return str(datetime.now() - self.startTime)
def reset_time(self):
self.startTime = datetime.now()
def get_score(self):
return self.score
def _is_line(self, markList, mark, direction):
for i in range(1, self.winRowLength):
seeked = (mark[0] + direction[0] * i, mark[1] + direction[1] * i)
if seeked in markList:
continue
else:
return False
return True

View File

@ -18,15 +18,17 @@ class GameMap:
def add_mark(self, x, y, player):
# Can be 0 or can be a max value, so,
# this is border-inclusive.
if (x <= self.max_size_x and y <= self.max_size_y) and (x >= 0 and y >= 0):
if (x, y) not in self.data:
self.data[(x,y)] = player
player.add_mark((x,y))
player.add_mark(x,y)
else:
errorMessage = "The mark is already busy by the Player " + str(self.data[(x, y)].get_name())
errorMessage = "The mark is already busy by the player '" + str(self.data[(x, y)].get_name()) + "'"
raise KeyError(errorMessage)
else:
errorMessage = "The mark" + str((x,y)) + " is beyond preset max values, max_x - " + str(self.max_size_x) + ", max_y - " + str(self.max_size_y)
errorMessage = "The mark" + str((x,y)) + " is beyond preset max values or 0, max_x - " + str(self.max_size_x) + ", max_y - " + str(self.max_size_y)
raise IndexError(errorMessage)

36
Interface.py Normal file
View File

@ -0,0 +1,36 @@
from tkinter import *
import Constants
def generate_new_settings_window():
window = Tk()
window.geometry("400x300+300+250")
window.title("Tic-Far-Toe v{}".format(Constants.VERSION_NUMBER))
main_menu = Menu(tearoff=0)
file_menu = Menu(tearoff=0)
main_menu.add_cascade(label="File", menu=file_menu)
# TODO - Fix this button that somehow spawns a broken window with no menus
file_menu.add_command(label="New", command=generate_new_settings_window)
file_menu.add_command(label="Save")
file_menu.add_command(label="Save As...")
file_menu.add_command(label="Load", command=generate_file_select_window)
file_menu.add_separator()
file_menu.add_command(label="Exit")
edit_menu = Menu(tearoff=0)
main_menu.add_cascade(label="Edit", menu=edit_menu)
view_menu = Menu(tearoff=0)
main_menu.add_cascade(label="View", menu=view_menu)
window.config(menu=main_menu)
window.mainloop()
def generate_new_game_window():
pass
def generate_file_select_window():
pass

View File

@ -1,2 +1,5 @@
import pygame
from GameLogic import *
from Interface import *
from GameLogic import *
VERSION_NUMBER = "0.1"
generate_new_settings_window()

View File

@ -1,16 +1,25 @@
class Player():
def __init__(self, name):
def __init__(self, name, personalScore=0):
self.name = name
self.markList = []
self.personalScore = personalScore
def __str__(self):
return "Player " + self.name + ': ' + "\n " + str(self.markList)
def get_markList(self):
return self.markList
def get_name(self):
return self.name
def add_mark(self, x, y):
self.markList.append((x, y))
self.markList.append((x, y))
self.personalScore += 10
def clear_mark_list():
self.markList = []

18
Timer.py Normal file
View File

@ -0,0 +1,18 @@
from datetime import datetime, time
class Timer():
def __init__(self):
self.startTime = 0
def has_second_passed(self):
return self.get_time() > 1
def get_time(self):
return str(datetime.now() - self.startTime)
def reset_time(self):
self.startTime = datetime.now()

27
tester.py Normal file
View File

@ -0,0 +1,27 @@
from GameLogic import *
from unittest import *
gmap = GameMap(10, 10)
player1 = Player("first")
player2 = Player("second")
playerList = [player1, player2]
gmap.add_mark(4, 4, player1)
gmap.add_mark(4, 5, player1)
gmap.add_mark(4, 6, player1)
gmap.add_mark(10, 10, player2)
gmap = gameMap(5, 5)
print(gmap)
print(player1)
print(player2)
glogic = GameLogic(GameMap, playerList)
print(glogic.check_who_win())
# AAAAAAAAAAAA I AM GOING INSANE OVER THIS BULLSHIELD
# Outdated this message is, I will just work with tuple[0] and tuple[1].
# ----
# Anyway, a reminder when you'll get to the web - figure out how to manipulate
# tuples (or replace them altogether) so they'll behave like math matrices -
# as in, (4, 4) * 2 -> (8, 8), and as in, (4, 4) + (-2, 3) -> (2, 7)