diff --git a/.gitignore b/.gitignore index e2c27b0..1a3f0ca 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ PlayerBase_func.pybak __pycache__ maze/__pycache__ maze/modules/__pycache__ -saves \ No newline at end of file +saves +tetris \ No newline at end of file diff --git a/credentials.pickle b/credentials.pickle index 452764f..093f73c 100644 Binary files a/credentials.pickle and b/credentials.pickle differ diff --git a/maze/modules/PlayerBase_func.py b/maze/modules/PlayerBase_func.py index 1f3a72b..73816a8 100644 --- a/maze/modules/PlayerBase_func.py +++ b/maze/modules/PlayerBase_func.py @@ -26,7 +26,7 @@ with open("credentials.pickle", "rb") as f: if d["credtype"] == "mysql": MYSQL_USERNAME = d["user"] MYSQL_PASSWORD = d["pass"] - except EOFError: + except: pass diff --git a/maze/modules/__init__.py b/maze/modules/__init__.py index eb35b5a..f5e3528 100644 --- a/maze/modules/__init__.py +++ b/maze/modules/__init__.py @@ -5,3 +5,6 @@ from maze.modules.maze import main def bruh(): curses.wrapper(main) + curses.nocbreak() + curses.echo() + curses.endwin() diff --git a/maze/modules/maze.py b/maze/modules/maze.py index a4ded71..9a5c058 100644 --- a/maze/modules/maze.py +++ b/maze/modules/maze.py @@ -141,7 +141,7 @@ class Maze: 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]) nodes_to_explore = [start] explored_nodes = set() @@ -174,7 +174,9 @@ def path(maze, start, finish): # Not used 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: head = ("█", curses.color_pair(2)) if not trail: @@ -221,11 +223,14 @@ def construction_demo(maze, screen): 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 = [] finish = [] solution = None old_solution = None + def reset(start_or_finish, cell, colour): nonlocal solution, old_solution 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) if start and finish: 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() - + if loadedcoords: current_coords = list(loadedcoords) cell = (int(current_coords[0] / 2), int(current_coords[1] / 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: - #current_coords = [maxy - 5, maxx - 27] + # current_coords = [maxy - 5, maxx - 27] current_coords = [1, 1] screen.addstr(current_coords[0], current_coords[1], "█", curses.color_pair(2)) WALL = ["═", "║", "╗", "╚", "╝", "╔", "╠", "╣", "╦", "╩", "╬", "═", "═", "║", "║"] @@ -266,7 +272,9 @@ def pathfinding_demo(maze, screen, start_ts, won_coords, loadedcoords=None, load PAUSED = False break 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.refresh() key = screen.getch() @@ -531,9 +539,9 @@ def play(screen, loadedmaze=None, loadedcoords=None, loadedtime=0): def main(screen): + screen.nodelay(True) curses.curs_set(False) curses.mousemask(curses.ALL_MOUSE_EVENTS) - screen.nodelay(True) curses.init_pair(1, curses.COLOR_BLUE, curses.COLOR_BLACK) curses.init_pair(2, curses.COLOR_GREEN, curses.COLOR_BLACK) curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLACK) diff --git a/pong.py b/pong.py new file mode 100644 index 0000000..4f26816 --- /dev/null +++ b/pong.py @@ -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) diff --git a/snake.py b/snake.py new file mode 100644 index 0000000..31c796e --- /dev/null +++ b/snake.py @@ -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) diff --git a/starter.py b/starter.py index 285a485..94f1a4d 100644 --- a/starter.py +++ b/starter.py @@ -16,7 +16,7 @@ with open("credentials.pickle", "rb") as f: user = d["user"] password = d["pass"] break - except EOFError: + except: user = password = None @@ -38,7 +38,7 @@ Run 'python starter.py initsql' to initialise credentials of your choice. """ d["pass"] = "" f.seek(pos) pickle.dump(d, f) - except EOFError: + except: pass return None, None @@ -53,9 +53,9 @@ else: databaseinit() subprocess.call( f"mysql -u {user} --password={password} -D labyrinth < {os.path.abspath('dbdump.sql')}", - shell=True#, - #stdout=subprocess.DEVNULL, - #stderr=subprocess.DEVNULL, + shell=True # , + # stdout=subprocess.DEVNULL, + # stderr=subprocess.DEVNULL, ) print("Successfully dumped sample data") elif sys.argv[1] == "initsql": @@ -71,6 +71,6 @@ else: d["pass"] = password f.seek(pos) pickle.dump(d, f) - except EOFError: + except: pass print("Successfully set.")