Introducing pong and snake

This commit is contained in:
adithyagenie 2022-11-23 23:33:16 +05:30
parent 640dbd9e8a
commit 149819fdd4
8 changed files with 334 additions and 17 deletions

3
.gitignore vendored
View file

@ -4,4 +4,5 @@ PlayerBase_func.pybak
__pycache__ __pycache__
maze/__pycache__ maze/__pycache__
maze/modules/__pycache__ maze/modules/__pycache__
saves saves
tetris

Binary file not shown.

View file

@ -26,7 +26,7 @@ with open("credentials.pickle", "rb") as f:
if d["credtype"] == "mysql": if d["credtype"] == "mysql":
MYSQL_USERNAME = d["user"] MYSQL_USERNAME = d["user"]
MYSQL_PASSWORD = d["pass"] MYSQL_PASSWORD = d["pass"]
except EOFError: except:
pass pass

View file

@ -5,3 +5,6 @@ from maze.modules.maze import main
def bruh(): def bruh():
curses.wrapper(main) curses.wrapper(main)
curses.nocbreak()
curses.echo()
curses.endwin()

View file

@ -141,7 +141,7 @@ class Maze:
return finalstr return finalstr
def path(maze, start, finish): # Not used def path(maze, start, finish):
heuristic = lambda node: abs(node[0] - finish[0]) + abs(node[1] - finish[1]) heuristic = lambda node: abs(node[0] - finish[0]) + abs(node[1] - finish[1])
nodes_to_explore = [start] nodes_to_explore = [start]
explored_nodes = set() explored_nodes = set()
@ -174,7 +174,9 @@ def path(maze, start, finish): # Not used
nodes_to_explore.append(neighbour) nodes_to_explore.append(neighbour)
def draw_path(path, screen, delay=0, head=None, trail=None, skip_first=True, calledby=None): def draw_path(
path, screen, delay=0, head=None, trail=None, skip_first=True, calledby=None
):
if not head: if not head:
head = ("", curses.color_pair(2)) head = ("", curses.color_pair(2))
if not trail: if not trail:
@ -221,11 +223,14 @@ def construction_demo(maze, screen):
screen.nodelay(False) screen.nodelay(False)
def pathfinding_demo(maze, screen, start_ts, won_coords, loadedcoords=None, loadedtime=0): def pathfinding_demo(
maze, screen, start_ts, won_coords, loadedcoords=None, loadedtime=0
):
start = [] start = []
finish = [] finish = []
solution = None solution = None
old_solution = None old_solution = None
def reset(start_or_finish, cell, colour): def reset(start_or_finish, cell, colour):
nonlocal solution, old_solution nonlocal solution, old_solution
if start_or_finish: if start_or_finish:
@ -237,16 +242,17 @@ def pathfinding_demo(maze, screen, start_ts, won_coords, loadedcoords=None, load
start_or_finish.append(cell) start_or_finish.append(cell)
if start and finish: if start and finish:
solution, old_solution = tee(path(maze, start[0], finish[0])) solution, old_solution = tee(path(maze, start[0], finish[0]))
draw_path(solution, screen, calledby="reset") draw_path(solution, screen, calledby="reset")
maxy, maxx = screen.getmaxyx() maxy, maxx = screen.getmaxyx()
if loadedcoords: if loadedcoords:
current_coords = list(loadedcoords) current_coords = list(loadedcoords)
cell = (int(current_coords[0] / 2), int(current_coords[1] / 2)) cell = (int(current_coords[0] / 2), int(current_coords[1] / 2))
reset(finish, cell, curses.color_pair(2)) reset(finish, cell, curses.color_pair(2))
reset(start, (0,0), curses.color_pair(2)) reset(start, (0, 0), curses.color_pair(2))
else: else:
#current_coords = [maxy - 5, maxx - 27] # current_coords = [maxy - 5, maxx - 27]
current_coords = [1, 1] current_coords = [1, 1]
screen.addstr(current_coords[0], current_coords[1], "", curses.color_pair(2)) screen.addstr(current_coords[0], current_coords[1], "", curses.color_pair(2))
WALL = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", ""] WALL = ["", "", "", "", "", "", "", "", "", "", "", "", "", "", ""]
@ -266,7 +272,9 @@ def pathfinding_demo(maze, screen, start_ts, won_coords, loadedcoords=None, load
PAUSED = False PAUSED = False
break break
pause_elapsed += int(end_paused_ts - start_paused_ts) pause_elapsed += int(end_paused_ts - start_paused_ts)
actual_elapsed = str(int(time.time() - start_ts - -1*loadedtime) - pause_elapsed) actual_elapsed = str(
int(time.time() - start_ts - -1 * loadedtime) - pause_elapsed
)
screen.addstr(5, maxx - 17, actual_elapsed + " sec") screen.addstr(5, maxx - 17, actual_elapsed + " sec")
screen.refresh() screen.refresh()
key = screen.getch() key = screen.getch()
@ -531,9 +539,9 @@ def play(screen, loadedmaze=None, loadedcoords=None, loadedtime=0):
def main(screen): def main(screen):
screen.nodelay(True)
curses.curs_set(False) curses.curs_set(False)
curses.mousemask(curses.ALL_MOUSE_EVENTS) curses.mousemask(curses.ALL_MOUSE_EVENTS)
screen.nodelay(True)
curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK) curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK)
curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK)
curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK) curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK)

193
pong.py Normal file
View file

@ -0,0 +1,193 @@
import curses
import random
import threading
import time
from math import fabs
quit = threading.Event()
class Scores:
def __init__(self):
self.score = 0
self.collision_count = 0
self.speed_multiplier = 0.20
self.speed_calc = lambda speed: speed - 0.02 if self.score % 30 == 0 else speed
def scoreupdate(self):
self.score += 10
self.collision_count += 1
self.speed_multiplier = self.speed_calc(self.speed_multiplier)
return self.speed_multiplier
class Ball:
def __init__(self, y, x, screen):
self.ball_dx = 1
self.ball_dy = 1
self.speed_multipliery = random.choice([1, 2])
self.speed_multiplierx = random.choice([1, 2])
self.ball_dy *= self.speed_multipliery
self.ball_dx *= self.speed_multiplierx
self.ball_coords = [y // 2, x // 2]
self.y = y
self.x = x
self.y_border = [0, y]
self.x_border = [0, x]
self.screen = screen
def move(self):
raw_calc_to_movey = lambda y: y + self.ball_dy
raw_calc_to_movex = lambda x: x + self.ball_dx
raw_movey = raw_calc_to_movey(
self.ball_coords[0]
) # Gives raw about to move coords without speed alter
raw_movex = raw_calc_to_movex(self.ball_coords[1])
speed_altery = lambda y: int(y / fabs(y)) # Gives unit speed in the current dir
speed_alterx = lambda x: int(x / fabs(x))
calc_to_movey = (
lambda y: y + speed_altery(self.ball_dy)
if checky(raw_movey)
else y + self.ball_dy
) # assign same dir movement coords
calc_to_movex = (
lambda x: x + speed_alterx(self.ball_dx)
if checkx(raw_movex)
else x + self.ball_dx
)
checky = (
lambda y: True
if (y in self.y_border)
or (y >= self.y_border[1])
or (y <= self.y_border[0] + 1)
else False
) # Gives True if out of bound coords
checkx = (
lambda x: True
if (x in self.x_border)
or (x >= self.x_border[1] - 1)
or (x <= self.x_border[0] + 1)
else False
)
actual_game_checky = (
lambda y: True if (y <= self.y_border[0]) else False
) # Gives true if ball at top
to_movey = calc_to_movey(self.ball_coords[0]) # Moving here after speed alter
to_movex = calc_to_movex(self.ball_coords[1])
old_ball = self.ball_coords.copy()
collision = False
pos = self.screen.instr(to_movey, to_movex, 1).decode("utf-8")
if pos == "=" or pos == "[" or pos == "]":
collision = True
if (
actual_game_checky(to_movey) or collision
): # Deflect ball if top border/collision
self.ball_dy *= -1
elif to_movey >= self.y_border[1] and not collision:
return [None, None], [None, None], "OVER"
if checkx(to_movex):
self.ball_dx *= -1
self.ball_coords[0] += self.ball_dy
self.ball_coords[1] += self.ball_dx
if collision:
return self.ball_coords, old_ball, "collision"
return self.ball_coords, old_ball, "nocollision"
class Player:
def __init__(self, y, x):
self.y = y
self.x = x
self.paddle = "[=======]"
self.paddle_posx = x // 2
self.paddle_posy = y - 1 # Top of paddle
def player_move(self, dir):
if dir == "LEFT" and self.paddle_posx > 1:
self.paddle_posx -= 1
if dir == "RIGHT" and self.paddle_posx + 10 < self.x:
self.paddle_posx += 1
return self.paddle_posy, self.paddle_posx
def player_movement(screen, player):
global quit
screen.keypad(True)
while 1:
# f.write("player running\n")
if quit.is_set():
break
old_player_coordsy = player_coordsy = player.paddle_posy
old_player_coordsx = player_coordsx = player.paddle_posx
key = screen.getch()
if key == 27:
quit.set()
elif key == curses.KEY_LEFT:
player_coordsy, player_coordsx = player.player_move("LEFT")
elif key == curses.KEY_RIGHT:
player_coordsy, player_coordsx = player.player_move("RIGHT")
screen.addstr(old_player_coordsy, old_player_coordsx, " ")
screen.addstr(player_coordsy, player_coordsx, player.paddle)
def ball_movement(screen, ball, score):
y, x = screen.getmaxyx()
while 1:
# f.write("ball running\n")
if quit.is_set():
break
speed_multi = score.speed_multiplier
time.sleep(speed_multi)
ball_coords = ball.move()
old_ball_posy, old_ball_posx = ball_coords[1]
ball_posy, ball_posx = ball_coords[0]
collision = ball_coords[2]
if collision == "OVER":
finalscore = score.score
screen.addstr(y // 2 - 1, x // 2 - 4, "GAME OVER!")
screen.addstr(y // 2, x // 2 - 5, "The Score is: " + str(finalscore))
time.sleep(5)
quit.set()
break
elif collision == "collision":
score.scoreupdate()
screen.addch(old_ball_posy, old_ball_posx, " ")
screen.addch(ball_posy, ball_posx, "*")
screen.refresh()
def main(screen):
screen.clear()
screen.refresh()
screen.nodelay(True)
curses.curs_set(False)
screen.keypad(True)
y, x = screen.getmaxyx()
ball = Ball(y, x, screen)
score = Scores()
player = Player(y, x)
ball_thread = threading.Thread(
target=ball_movement,
args=(
screen,
ball,
score,
),
)
player_thread = threading.Thread(
target=player_movement,
args=(
screen,
player,
),
)
ball_thread.start()
player_thread.run()
# player_movement(screen, player)
if __name__ == "__main__":
curses.wrapper(main)

112
snake.py Normal file
View file

@ -0,0 +1,112 @@
import curses
import random
import time
from curses import textpad
OPPOSITE_DIRECTION_DICT = {
curses.KEY_UP: curses.KEY_DOWN,
curses.KEY_DOWN: curses.KEY_UP,
curses.KEY_RIGHT: curses.KEY_LEFT,
curses.KEY_LEFT: curses.KEY_RIGHT,
}
DIRECTIONS_LIST = [curses.KEY_RIGHT, curses.KEY_LEFT, curses.KEY_DOWN, curses.KEY_UP]
def create_food(snake, box):
"""Simple function to find coordinates of food which is inside box and not on snake body"""
food = None
while food is None:
food = [
random.randint(box[0][0] + 1, box[1][0] - 1),
random.randint(box[0][1] + 1, box[1][1] - 1),
]
if food in snake:
food = None
return food
def main(stdscr):
# initial settings
curses.curs_set(0)
stdscr.nodelay(1)
stdscr.timeout(100)
# create a game box
sh, sw = stdscr.getmaxyx()
box = [[3, 3], [sh - 3, sw - 3]] # [[ul_y, ul_x], [dr_y, dr_x]]
textpad.rectangle(stdscr, box[0][0], box[0][1], box[1][0], box[1][1])
# create snake and set initial direction
snake = [[sh // 2, sw // 2 + 1], [sh // 2, sw // 2], [sh // 2, sw // 2 - 1]]
direction = curses.KEY_RIGHT
# draw snake
for y, x in snake:
stdscr.addstr(y, x, "#")
# create food
food = create_food(snake, box)
stdscr.addstr(food[0], food[1], "*")
# print score
score = 0
score_text = "Score: {}".format(score)
stdscr.addstr(1, sw // 2 - len(score_text) // 2, score_text)
while 1:
# non-blocking input
key = stdscr.getch()
# set direction if user pressed any arrow key and that key is not opposite of current direction
if key in DIRECTIONS_LIST and key != OPPOSITE_DIRECTION_DICT[direction]:
direction = key
# find next position of snake head
head = snake[0]
if direction == curses.KEY_RIGHT:
new_head = [head[0], head[1] + 1]
elif direction == curses.KEY_LEFT:
new_head = [head[0], head[1] - 1]
elif direction == curses.KEY_DOWN:
new_head = [head[0] + 1, head[1]]
elif direction == curses.KEY_UP:
new_head = [head[0] - 1, head[1]]
# insert and print new head
stdscr.addstr(new_head[0], new_head[1], "#")
snake.insert(0, new_head)
# if sanke head is on food
if snake[0] == food:
# update score
score += 1
score_text = "Score: {}".format(score)
stdscr.addstr(1, sw // 2 - len(score_text) // 2, score_text)
# create new food
food = create_food(snake, box)
stdscr.addstr(food[0], food[1], "*")
# increase speed of game
stdscr.timeout(100 - (len(snake) // 3) % 90)
else:
# shift snake's tail
stdscr.addstr(snake[-1][0], snake[-1][1], " ")
snake.pop()
# conditions for game over
if (
snake[0][0] in [box[0][0], box[1][0]]
or snake[0][1] in [box[0][1], box[1][1]]
or snake[0] in snake[1:]
):
msg = "Game Over!"
stdscr.addstr(sh // 2, sw // 2 - len(msg) // 2, msg)
stdscr.nodelay(0)
stdscr.getch()
time.sleep(5)
break
curses.wrapper(main)

View file

@ -16,7 +16,7 @@ with open("credentials.pickle", "rb") as f:
user = d["user"] user = d["user"]
password = d["pass"] password = d["pass"]
break break
except EOFError: except:
user = password = None user = password = None
@ -38,7 +38,7 @@ Run 'python starter.py initsql' to initialise credentials of your choice. """
d["pass"] = "" d["pass"] = ""
f.seek(pos) f.seek(pos)
pickle.dump(d, f) pickle.dump(d, f)
except EOFError: except:
pass pass
return None, None return None, None
@ -53,9 +53,9 @@ else:
databaseinit() databaseinit()
subprocess.call( subprocess.call(
f"mysql -u {user} --password={password} -D labyrinth < {os.path.abspath('dbdump.sql')}", f"mysql -u {user} --password={password} -D labyrinth < {os.path.abspath('dbdump.sql')}",
shell=True#, shell=True # ,
#stdout=subprocess.DEVNULL, # stdout=subprocess.DEVNULL,
#stderr=subprocess.DEVNULL, # stderr=subprocess.DEVNULL,
) )
print("Successfully dumped sample data") print("Successfully dumped sample data")
elif sys.argv[1] == "initsql": elif sys.argv[1] == "initsql":
@ -71,6 +71,6 @@ else:
d["pass"] = password d["pass"] = password
f.seek(pos) f.seek(pos)
pickle.dump(d, f) pickle.dump(d, f)
except EOFError: except:
pass pass
print("Successfully set.") print("Successfully set.")