diff --git a/course work/ai.py b/course work/ai.py new file mode 100644 index 0000000..85c3b61 --- /dev/null +++ b/course work/ai.py @@ -0,0 +1,112 @@ +import pygame +from copy import deepcopy + +class Event(): + type = None + key = None + + def __init__(self, type, key): + self.type = type + self.key = key + + +def check_border(figure, i, W, H, field): + if figure[i].x < (W-9) or figure[i].x > W: + return 0 + if W > 10: + if figure[i].y > H-1 or field[figure[i].y][figure[i].x]: + return 1 + else: + if figure[i].y > H-1 or field[figure[i].y][figure[i].x]: + return 1 + return 2 + + +def rotate(rotate_1, W, H, field_1, figure): + center_1 = figure[0] + figure_old_1 = deepcopy(figure) + if rotate_1: + for i in range(4): + x = figure[i].y - center_1.y + y = figure[i].x - center_1.x + figure[i].x = center_1.x - x + figure[i].y = center_1.y + y + if not check_border(figure, i, W, H, field_1): + figure = deepcopy(figure_old_1) + break + + +def add_figure(figure, field_1, W, H): + for i in range(4): + figure[i].y = 0 + while True: + for i in range(4): + figure[i].y += 1 + if check_border(figure, i, W, H, field_1) == 1: + for j in range(4): + field_1[figure[j].y][figure[j].x] = pygame.Color('white') + break + + + + +def get_height(field, W, H, figure): + height = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + temp_height = 0 + for i in field: + temp = 0 + for j in i: + if j != 0: + if height[temp] == 0: + height[temp] = H - temp_height + 1 + temp += 1 + temp_height += 1 + return height + + +def simulation(field, W, H, figure): + copy_figure = deepcopy(figure) + temp_field = deepcopy(field) + new = [] + for i in range(4): + rotate(True, W, H, temp_field, copy_figure) + add_figure(copy_figure, temp_field, W, H) + temp = get_height(temp_field, W, H, copy_figure) + temp = temp[1:] + new.append(sum(temp)) + temp_field = deepcopy(field) + temp = min(new) + rot_n = new.index(temp) + return rot_n + + +def best_position(x, height: list, field, W, H, figure): + e = [] + for i in range(simulation(field, W, H, figure)): + e.append(e.append(Event(pygame.KEYDOWN, pygame.K_UP))) + height = height[1:] + new_x = min(height) + find_x = height.index(new_x) + e = [] + if find_x == x-1: + e.append(Event(pygame.KEYDOWN, pygame.K_DOWN)) + if find_x > x: + e.append(Event(pygame.KEYDOWN, pygame.K_RIGHT)) + elif find_x < x: + e.append(Event(pygame.KEYDOWN, pygame.K_LEFT)) + return e + +dx = 0 +def get_dx(x): + global dx + dx = x - 1 + + +counter = 0 +def run_ai(field, figure, width, heig): + height = get_height(field, width, heig, figure) + global dx + global counter + counter += 1 + e = best_position(dx, height, field, width, heig, figure) + return e \ No newline at end of file diff --git a/course work/classic.py b/course work/classic.py new file mode 100644 index 0000000..7b39191 --- /dev/null +++ b/course work/classic.py @@ -0,0 +1,203 @@ +import pygame +from copy import deepcopy +from random import choice +from database import input_record +from test import check_nickname + + +def check_border(figure, i, W, H, field): + if figure[i].x < (W-9) or figure[i].x > W: + return 0 + if W > 10: + if figure[i].y > H or field[figure[i].y][figure[i].x]: + return 1 + else: + if figure[i].y > H or field[figure[i].y][figure[i].x]: + return 1 + return 2 + + +def rotate(rotate_1, W, H, field_1, figure): + center_1 = figure[0] + figure_old_1 = deepcopy(figure) + if rotate_1: + for i in range(4): + x = figure[i].y - center_1.y + y = figure[i].x - center_1.x + figure[i].x = center_1.x - x + figure[i].y = center_1.y + y + if not check_border(figure, i, W, H, field_1): + figure = deepcopy(figure_old_1) + break + + +def tetris_classic(TILE, W, H, clock, FPS, screen, menu): + sc = pygame.display.set_mode((1600, 1000)) + #get name + font = pygame.font.Font(None, 32) + input_box = pygame.Rect(500, 500, 140, 32) + color_inactive = pygame.Color('lightskyblue3') + color_active = pygame.Color('dodgerblue2') + color = color_inactive + active = False + nickname = '' + done = False + while not done: + for event in pygame.event.get(): + if event.type == pygame.QUIT: + done = True + if event.type == pygame.MOUSEBUTTONDOWN: + # If the user clicked on the input_box rect. + if input_box.collidepoint(event.pos): + # Toggle the active variable. + active = not active + else: + active = False + # Change the current color of the input box. + color = color_active if active else color_inactive + if event.type == pygame.KEYDOWN: + if active: + if event.key == pygame.K_RETURN: + done = True + elif event.key == pygame.K_BACKSPACE: + nickname = nickname[:-1] + else: + nickname += event.unicode + screen.fill((30, 30, 30)) + # Render the current text. + txt_surface = font.render(nickname, True, color) + # Resize the box if the text is too long. + width = max(200, txt_surface.get_width()+10) + input_box.w = width + # Blit the text. + screen.blit(txt_surface, (input_box.x+5, input_box.y+5)) + # Blit the input_box rect. + pygame.draw.rect(screen, color, input_box, 2) + pygame.display.flip() + + #test input nickname + check_nickname(nickname) + score = 0 + scores = {0:0, 1:100, 2:300, 3:700, 4:1500} + lines = 0 + + anim_count_1, anim_limit_1 = 0, 2000 + anim_speed_1= 60 + #first grid + grid = [pygame.Rect(x * TILE, y * TILE, TILE, TILE) for x in range(1, W+1) for y in range(1, H+1)] + + figures_pos = [[(0, 1), (-1, 1), (1, 1), (2, 1)], + [(1, 0), (0, 0), (0, 1), (1, 1)], + [(0, 1), (0, 2), (1, 1), (1, 0)], + [(1, 1), (0, 1), (1, 2), (0, 0)], + [(1, 1), (1, 0), (1, 2), (0, 0)], + [(1, 1), (1, 0), (1, 2), (2, 0)], + [(1, 1), (1, 0), (1, 2), (0, 1)]] + + figures = [[pygame.Rect(x + (W+1) // 2, y + 1, 1, 1) for x, y in fig_pos] for fig_pos in figures_pos] + figure_rect = pygame.Rect(0, 0, TILE - 2, TILE - 2) + + figure = deepcopy(choice(figures)) + field = [[0 for i in range(W+1)] for j in range(H+1)] + + flag = 0 + while True: + rotate_1 = False + dx_1 = 0 + screen.fill(pygame.Color('black')) + #control first + for event in pygame.event.get(): + if event.type == pygame.QUIT: + exit() + if event.type == pygame.KEYDOWN: + #menu + if event.key == pygame.K_ESCAPE: + menu.mainloop(screen) + #control first + if event.key == pygame.K_LEFT: + dx_1 = -1 + if event.key == pygame.K_RIGHT: + dx_1 = 1 + if event.key == pygame.K_DOWN: + anim_limit_1 = 100 + if event.key == pygame.K_UP: + rotate_1 = True + #move x + figure_old = deepcopy(figure) + for i in range(4): + figure[i].x += dx_1 + if not check_border(figure, i, W, H, field): + figure = deepcopy(figure_old) + anim_limit_1 = 2000 + break + #move y + anim_count_1 += anim_speed_1 + if anim_count_1 > anim_limit_1: + anim_count_1 = 0 + figure_old_1 = deepcopy(figure) + for i in range(4): + figure[i].y += 1 + if check_border(figure, i, W, H, field) == 1: + for i in range(4): + field[figure_old_1[i].y][figure_old_1[i].x] = pygame.Color('white') + figure = deepcopy(choice(figures)) + anim_limit_1 = 2000 + break + elif check_border(figure, i, W, H, field) == 0: + figure = deepcopy(figure_old_1) + #wrap/rotate + rotate(rotate_1, W, H, field, figure) + #check lines + line = H + lines = 0 + for row in range(H, -1, -1): + count = 0 + for i in range(1, W+1): + if field[row][i]: + count += 1 + field[line][i] = field[row][i] + if count < W: + line -= 1 + else: + anim_speed_1 += 5 + lines += 1 + score += scores[lines] + + #draw grid + [pygame.draw.rect(screen, (40, 40, 40), i_rect, 1) for i_rect in grid] + #draw figure + for i in range(4): + figure_rect.x = figure[i].x * TILE + figure_rect.y = figure[i].y * TILE + pygame.draw.rect(screen, pygame.Color('white'), figure_rect) + #draw field + for y, raw in enumerate(field): + for x, col in enumerate(raw): + if col: + figure_rect.x, figure_rect.y = x * TILE, y * TILE + pygame.draw.rect(screen, col, figure_rect) + + font = pygame.font.SysFont(None, 68) + title_tetris = font.render('TETRIS', True, pygame.Color('white')) + title_score = font.render('SCORE:', True, pygame.Color('white')) + result_score = font.render(str(score), True, pygame.Color('white')) + + sc.blit(title_tetris, (510, 50)) + sc.blit(title_score, (510, 800)) + sc.blit(result_score, (510, 850)) + #game over + for i in range(W+1): + if field[1][i]: + flag += 1 + result = "Your score: " + str(score) + result_score = font.render(str(result), True, pygame.Color('white')) + screen.fill(pygame.Color('black')) + sc.blit(result_score, (800, 500)) + + if flag == 1: + input_record(nickname, score) + + pygame.display.flip() + clock.tick(FPS) + + diff --git a/course work/config.py b/course work/config.py new file mode 100644 index 0000000..3f203bd --- /dev/null +++ b/course work/config.py @@ -0,0 +1,4 @@ +host = "127.0.0.1" +user = "postgres" +password = "postgres29" +db_name = "labs" \ No newline at end of file diff --git a/course work/database.py b/course work/database.py new file mode 100644 index 0000000..3bdc6a3 --- /dev/null +++ b/course work/database.py @@ -0,0 +1,64 @@ +import psycopg2 +from config import host, user, password, db_name + + +def get_record(): + try: + #login in db + connection = psycopg2.connect( + host = host, + user = user, + password = password, + database = db_name, + ) + connection.autocommit = True + + with connection.cursor() as cursor: + cursor.execute( + """SELECT nickname, score FROM record ORDER BY score""" + ) + result = cursor.fetchall() + + except Exception as _ex: + print("[INFO] Error while working with PostgreSQL", _ex) + finally: + #end of word with db + if connection: + connection.close() + + return result + + +def input_record(nickname, score): + try: + #login in db + connection = psycopg2.connect( + host = host, + user = user, + password = password, + database = db_name, + ) + connection.autocommit = True + + #add new data to db + with connection.cursor() as cursor: + cursor.execute( + """INSERT INTO record (nickname, score) VALUES ('{0}', {1})""". + format(str(nickname), str(score)) + ) + + except Exception as _ex: + print("[INFO] Error while working with PostgreSQL", _ex) + finally: + #end of word with db + if connection: + connection.close() + +def main(): + result = get_record() + result.reverse() + print(result[0:10]) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/course work/main.py b/course work/main.py new file mode 100644 index 0000000..89da5cb --- /dev/null +++ b/course work/main.py @@ -0,0 +1,302 @@ +import pygame +from copy import deepcopy +from random import choice, randint +import pygame_menu +from classic import tetris_classic +from table import table +from tetris_ai import bot + +def check_border(figure, i, W, H, field): + if figure[i].x < (W-9) or figure[i].x > W: + return 0 + if W > 10: + if figure[i].y > H or field[figure[i].y][figure[i].x]: + return 1 + else: + if figure[i].y > H or field[figure[i].y][figure[i].x]: + return 1 + return 2 + + +def rotate(rotate_1, W, H, field_1, figure): + center_1 = figure[0] + figure_old_1 = deepcopy(figure) + if rotate_1: + for i in range(4): + x = figure[i].y - center_1.y + y = figure[i].x - center_1.x + figure[i].x = center_1.x - x + figure[i].y = center_1.y + y + if not check_border(figure, i, W, H, field_1): + figure = deepcopy(figure_old_1) + break + + +def pVSp(TILE, W, H, clock, FPS, screen, bot_user, menu): + sc = pygame.display.set_mode((1600, 1000)) + score_1, score_2 = 0, 0 + scores = {0:0, 1:100, 2:300, 3:700, 4:1500} + lines = 0 + + anim_count_1, anim_count_2, anim_limit_1, anim_limit_2 = 0, 0, 2000, 2000 + anim_speed_1, anim_speed_2 = 60, 60 + #first grid + grid = [pygame.Rect(x * TILE, y * TILE, TILE, TILE) for x in range(1, W+1) for y in range(1, H+1)] + #second grid + grid_2 = [pygame.Rect(x * TILE, y * TILE, TILE, TILE) for x in range(W+6, 2*W+6) for y in range(1, H+1)] + + figures_pos = [[(0, 1), (-1, 1), (1, 1), (2, 1)], + [(1, 0), (0, 0), (0, 1), (1, 1)], + [(0, 1), (0, 2), (1, 1), (1, 0)], + [(1, 1), (0, 1), (1, 2), (0, 0)], + [(1, 1), (1, 0), (1, 2), (0, 0)], + [(1, 1), (1, 0), (1, 2), (2, 0)], + [(1, 1), (1, 0), (1, 2), (0, 1)]] + + figures = [[pygame.Rect(x + (W+1) // 2, y + 1, 1, 1) for x, y in fig_pos] for fig_pos in figures_pos] + figures_2 = [[pygame.Rect(x + W+10, y + 1, 1, 1) for x, y in fig_pos] for fig_pos in figures_pos] + figure_rect = pygame.Rect(0, 0, TILE - 2, TILE - 2) + + figure = deepcopy(choice(figures)) + figure_2 = deepcopy(choice(figures_2)) + field_1 = [[0 for i in range(W+1)] for j in range(H+1)] + field_2 = [[0 for i in range(2*W+7)] for j in range(H+1)] + flag, input, lock = 0, 0, 0 + + + while True: + rotate_1, rotate_2 = False, False + dx_1 = 0 + dx_2 = 0 + screen.fill(pygame.Color('black')) + #control first + for event in pygame.event.get(): + if event.type == pygame.QUIT: + exit() + if event.type == pygame.KEYDOWN: + #menu + if event.key == pygame.K_ESCAPE: + menu.mainloop(screen) + #control first + if event.key == pygame.K_LEFT: + dx_1 = -1 + if event.key == pygame.K_RIGHT: + dx_1 = 1 + if event.key == pygame.K_DOWN: + anim_limit_1 = 100 + if event.key == pygame.K_UP: + rotate_1 = True + if bot_user == 0: + #control second + if event.key == pygame.K_a: + dx_2 = -1 + if event.key == pygame.K_d: + dx_2 = 1 + if event.key == pygame.K_s: + anim_limit_2 = 100 + if event.key == pygame.K_w: + rotate_2 = True + + if bot_user == 1: + if input % 51 == 0: + temp = randint(0, 20) + if lock == 1: + temp = -1 + else: + temp = -1 + if temp in [0, 1, 19, 20]: + dx_2 = -1 + if temp in [5, 2, 3, 18]: + dx_2 = 1 + if temp in [4]: + anim_limit_2 = 100 + if temp in [6, 7, 16, 17]: + rotate_2 = True + if temp in [8, 9, 10, 11, 12, 13, 14, 15]: + pass + input += 1 + #move x + figure_old_1 = deepcopy(figure) + for i in range(4): + figure[i].x += dx_1 + if not check_border(figure, i, W, H, field_1): + figure = deepcopy(figure_old_1) + anim_limit_1 = 2000 + break + + figure_old_2 = deepcopy(figure_2) + for i in range(4): + figure_2[i].x += dx_2 + if not check_border(figure_2, i, W+15, H, field_2): + figure_2 = deepcopy(figure_old_2) + anim_limit_2 = 2000 + break + #move y + anim_count_1 += anim_speed_1 + anim_count_2 += anim_speed_2 + if anim_count_1 > anim_limit_1: + anim_count_1 = 0 + figure_old_1 = deepcopy(figure) + for i in range(4): + figure[i].y += 1 + if check_border(figure, i, W, H, field_1) == 1: + for i in range(4): + field_1[figure_old_1[i].y][figure_old_1[i].x] = pygame.Color('white') + figure = deepcopy(choice(figures)) + anim_limit_1 = 2000 + break + elif check_border(figure, i, W, H, field_1) == 0: + figure = deepcopy(figure_old_1) + if anim_count_2 > anim_limit_2: + anim_count_2 = 0 + figure_old_2 = deepcopy(figure_2) + for i in range(4): + figure_2[i].y += 1 + if check_border(figure_2, i, W+15, H, field_2) == 1: + for i in range(4): + try: + field_2[figure_old_2[i].y][figure_old_2[i].x] = pygame.Color('white') + except: + pass + figure_2 = deepcopy(choice(figures_2)) + anim_limit_2 = 2000 + break + elif check_border(figure_2, i, W+15, H, field_2) == 0: + figure_2 = deepcopy(figure_old_2) + break + #wrap/rotate + rotate(rotate_1, W, H, field_1, figure) + rotate(rotate_2, W+15, H, field_2, figure_2) + #check lines + line = H + lines = 0 + for row in range(H, -1, -1): + count = 0 + for i in range(1, W+1): + if field_1[row][i]: + count += 1 + field_1[line][i] = field_1[row][i] + if count < W: + line -= 1 + else: + anim_speed_1 += 5 + lines += 1 + score_1 += scores[lines] + + lines = 0 + line = H + for row in range(H, -1, -1): + count = 0 + for i in range(1, W+1): + i += 15 + if field_2[row][i]: + count += 1 + field_2[line][i] = field_2[row][i] + if count < W: + line -= 1 + else: + anim_speed_2 += 5 + lines += 1 + + score_2 += scores[lines] + + #draw grid + [pygame.draw.rect(screen, (40, 40, 40), i_rect, 1) for i_rect in grid] + #draw second grid + [pygame.draw.rect(screen, (40, 40, 40), i_rect, 1) for i_rect in grid_2] + #draw figure + for i in range(4): + figure_rect.x = figure[i].x * TILE + figure_rect.y = figure[i].y * TILE + pygame.draw.rect(screen, pygame.Color('white'), figure_rect) + + figure_rect.x = figure_2[i].x * TILE + figure_rect.y = figure_2[i].y * TILE + pygame.draw.rect(screen, pygame.Color('white'), figure_rect) + #draw field + for y, raw in enumerate(field_1): + for x, col in enumerate(raw): + if col: + figure_rect.x, figure_rect.y = x * TILE, y * TILE + pygame.draw.rect(screen, col, figure_rect) + + for y, raw in enumerate(field_2): + for x, col in enumerate(raw): + if col: + figure_rect.x, figure_rect.y = x * TILE, y * TILE + pygame.draw.rect(screen, col, figure_rect) + + font = pygame.font.SysFont(None, 68) + title_tetris = font.render('TETRIS', True, pygame.Color('white')) + title_score = font.render('SCORE:', True, pygame.Color('white')) + result_score_1 = font.render(str(score_1), True, pygame.Color('white')) + result_score_2 = font.render(str(score_2), True, pygame.Color('white')) + + sc.blit(title_tetris, (510, 50)) + sc.blit(title_tetris, (1180, 50)) + + sc.blit(title_score, (510, 800)) + sc.blit(title_score, (1180, 800)) + + sc.blit(result_score_1, (510, 850)) + sc.blit(result_score_2, (1180, 850)) + + #game over + for i in range(W+1): + if field_1[1][i]: + field_1 = [[0 for i in range(W+1)] for j in range(H+1)] + anim_count_1, anim_speed_1, anim_limit_1 = 0, 0, 0 + pygame.display.flip() + flag += 1 + + + for i in range(2*W+7-11, 2*W+7): + if field_2[1][i]: + field_2 = [[0 for i in range(2*W+7)] for j in range(H+1)] + anim_count_2, anim_speed_2, anim_limit_2 = 0, 0, 0 + pygame.display.flip() + flag += 1 + lock = 1 + + if flag == 2: + if score_1 > score_2: + result = "Player 1 WIN" + elif score_1 < score_2: + if bot_user == 1: + result = "Bot WIN" + if bot_user == 0: + result = "Player 2 WIN" + elif score_1 == score_2: + result = "DRAW" + + screen.fill(pygame.Color('black')) + title_result = font.render(result, True, pygame.Color('white')) + sc.blit(title_result, (800, 500)) + + pygame.display.flip() + clock.tick(FPS) + + +def main(): + pygame.init() + clock = pygame.time.Clock() + + RES = 1600, 1000 + screen = pygame.display.set_mode(RES) + W, H = 10, 20 + TILE = 45 + FPS = 60 + menu = pygame_menu.Menu('Welcome', 400, 410) + table_menu = pygame_menu.Menu('Top 10', 400, 600) + menu.add.button('Classic tetris', tetris_classic, TILE, W, H, clock, FPS, screen, menu) + menu.add.button('player vs bot', pVSp, TILE, W, H, clock, FPS, screen, 1, menu) + menu.add.button('player vs player', pVSp, TILE, W, H, clock, FPS, screen, 0, menu) + menu.add.button('bot vs bot', bot, TILE, W, H, clock, FPS, screen, 1, menu) + menu.add.button('top 10', table, table_menu, screen, menu) + menu.add.button('Quit', pygame_menu.events.EXIT) + menu.mainloop(screen) + + + +if __name__=='__main__': + main() \ No newline at end of file diff --git a/course work/requirements.txt b/course work/requirements.txt new file mode 100644 index 0000000..a1e87b5 Binary files /dev/null and b/course work/requirements.txt differ diff --git a/course work/table.py b/course work/table.py new file mode 100644 index 0000000..4d3e0d1 --- /dev/null +++ b/course work/table.py @@ -0,0 +1,20 @@ +from database import get_record +import pygame_menu +from database import get_record + + +def table(menu: pygame_menu.Menu, screen, back_menu): + result = get_record() + result.reverse() + number = 0 + for i in result[0:10]: + number += 1 + row = str(number) + " " + i[0] + " " + str(i[1]) + menu.add.label(row) + menu.add.button('Back', back_menu) + menu.mainloop(screen) + + + +if __name__=="__main__": + table() \ No newline at end of file diff --git a/course work/test.py b/course work/test.py new file mode 100644 index 0000000..14ab254 --- /dev/null +++ b/course work/test.py @@ -0,0 +1,42 @@ +from database import * + + +def test_database(): + input_record('test', 10) + print("Put test and 10") + result = get_record() + for i in result: + if i == ('test', 10): + print("Get test and 10") + return 1 + print("Can't get") + return 0 + + +def check_output_database(): + result = get_record() + if result != None: + print("DB work") + return 1 + if result == None: + print("DB don't work") + return 0 + + +def check_nickname(nickname): + if nickname != None and nickname != "": + print("Test completed GOOD") + if nickname == "": + print("NICKNAME DON'T GET") + else: + print("NICKNAME DON'T GET") + + +if __name__=="__main__": + good_test = 0 + sum_test = 2 + test_1 = test_database() + test_2 = check_output_database() + good_test += test_1 + good_test += test_2 + print("{0} out of {1} completed successfully".format(good_test, sum_test)) \ No newline at end of file diff --git a/course work/tetris_ai.py b/course work/tetris_ai.py new file mode 100644 index 0000000..59b95f6 --- /dev/null +++ b/course work/tetris_ai.py @@ -0,0 +1,297 @@ +import pygame +from copy import deepcopy +from random import choice +from random import randint +import pygame_menu +import ai + + +def check_border(figure, i, W, H, field): + if figure[i].x < (W-9) or figure[i].x > W: + return 0 + if W > 10: + if figure[i].y > H or field[figure[i].y][figure[i].x]: + return 1 + else: + if figure[i].y > H or field[figure[i].y][figure[i].x]: + return 1 + return 2 + + +def rotate(rotate_1, W, H, field_1, figure): + center_1 = figure[0] + figure_old_1 = deepcopy(figure) + if rotate_1: + for i in range(4): + x = figure[i].y - center_1.y + y = figure[i].x - center_1.x + figure[i].x = center_1.x - x + figure[i].y = center_1.y + y + if not check_border(figure, i, W, H, field_1): + figure = deepcopy(figure_old_1) + break + + +def bot(TILE, W, H, clock, FPS, screen, bot_user, menu): + sc = pygame.display.set_mode((1600, 1000)) + score_1, score_2 = 0, 0 + scores = {0:0, 1:100, 2:300, 3:700, 4:1500} + lines = 0 + + anim_count_1, anim_count_2, anim_limit_1, anim_limit_2 = 0, 0, 2000, 2000 + anim_speed_1, anim_speed_2 = 60, 60 + #first grid + grid = [pygame.Rect(x * TILE, y * TILE, TILE, TILE) for x in range(1, W+1) for y in range(1, H+1)] + #second grid + grid_2 = [pygame.Rect(x * TILE, y * TILE, TILE, TILE) for x in range(W+6, 2*W+6) for y in range(1, H+1)] + + figures_pos = [[(0, 1), (-1, 1), (1, 1), (2, 1)], + [(1, 0), (0, 0), (0, 1), (1, 1)], + [(0, 1), (0, 2), (1, 1), (1, 0)], + [(1, 1), (0, 1), (1, 2), (0, 0)], + [(1, 1), (1, 0), (1, 2), (0, 0)], + [(1, 1), (1, 0), (1, 2), (2, 0)], + [(1, 1), (1, 0), (1, 2), (0, 1)]] + + figures = [[pygame.Rect(x + (W+1) // 2, y + 1, 1, 1) for x, y in fig_pos] for fig_pos in figures_pos] + figures_2 = [[pygame.Rect(x + W+10, y + 1, 1, 1) for x, y in fig_pos] for fig_pos in figures_pos] + figure_rect = pygame.Rect(0, 0, TILE - 2, TILE - 2) + + figure = deepcopy(choice(figures)) + figure_2 = deepcopy(choice(figures_2)) + field_1 = [[0 for i in range(W+1)] for j in range(H+1)] + field_2 = [[0 for i in range(2*W+7)] for j in range(H+1)] + flag, input, lock = 0, 0, 0 + + + while True: + rotate_1, rotate_2 = False, False + dx_1 = 0 + dx_2 = 0 + screen.fill(pygame.Color('black')) + #control first + for event in list(pygame.event.get()) + ai.run_ai( + field_1, figure, W, H): + if event.type == pygame.QUIT: + exit() + if event.type == pygame.KEYDOWN: + #menu + if event.key == pygame.K_ESCAPE: + menu.mainloop(screen) + #control first + if event.key == pygame.K_LEFT: + dx_1 = -1 + if event.key == pygame.K_RIGHT: + dx_1 = 1 + if event.key == pygame.K_DOWN: + anim_limit_1 = 100 + if event.key == pygame.K_UP: + rotate_1 = True + if bot_user == 0: + #control second + if event.key == pygame.K_a: + dx_2 = -1 + if event.key == pygame.K_d: + dx_2 = 1 + if event.key == pygame.K_s: + anim_limit_2 = 100 + if event.key == pygame.K_w: + rotate_2 = True + + if bot_user == 1: + if input % 51 == 0: + temp = randint(0, 20) + if lock == 1: + temp = -1 + else: + temp = -1 + if temp in [0, 1, 19, 20]: + dx_2 = -1 + if temp in [5, 2, 3, 18]: + dx_2 = 1 + if temp in [4]: + anim_limit_2 = 100 + if temp in [6, 7, 16, 17]: + rotate_2 = True + if temp in [8, 9, 10, 11, 12, 13, 14, 15]: + pass + input += 1 + #move x + figure_old_1 = deepcopy(figure) + for i in range(4): + figure[i].x += dx_1 + if not check_border(figure, i, W, H, field_1): + figure = deepcopy(figure_old_1) + anim_limit_1 = 2000 + break + + ai.get_dx(figure[2].x) + figure_old_2 = deepcopy(figure_2) + for i in range(4): + figure_2[i].x += dx_2 + if not check_border(figure_2, i, W+15, H, field_2): + figure_2 = deepcopy(figure_old_2) + anim_limit_2 = 2000 + break + #move y + anim_count_1 += anim_speed_1 + anim_count_2 += anim_speed_2 + if anim_count_1 > anim_limit_1: + anim_count_1 = 0 + figure_old_1 = deepcopy(figure) + for i in range(4): + figure[i].y += 1 + if check_border(figure, i, W, H, field_1) == 1: + for i in range(4): + field_1[figure_old_1[i].y][figure_old_1[i].x] = pygame.Color('white') + figure = deepcopy(choice(figures)) + anim_limit_1 = 2000 + break + elif check_border(figure, i, W, H, field_1) == 0: + figure = deepcopy(figure_old_1) + if anim_count_2 > anim_limit_2: + anim_count_2 = 0 + figure_old_2 = deepcopy(figure_2) + for i in range(4): + figure_2[i].y += 1 + if check_border(figure_2, i, W+15, H, field_2) == 1: + for i in range(4): + try: + field_2[figure_old_2[i].y][figure_old_2[i].x] = pygame.Color('white') + except: + pass + figure_2 = deepcopy(choice(figures_2)) + anim_limit_2 = 2000 + break + elif check_border(figure_2, i, W+15, H, field_2) == 0: + figure_2 = deepcopy(figure_old_2) + break + #wrap/rotate + rotate(rotate_1, W, H, field_1, figure) + rotate(rotate_2, W+15, H, field_2, figure_2) + #check lines + line = H + lines = 0 + for row in range(H, -1, -1): + count = 0 + for i in range(1, W+1): + if field_1[row][i]: + count += 1 + field_1[line][i] = field_1[row][i] + if count < W: + line -= 1 + else: + anim_speed_1 += 5 + lines += 1 + score_1 += scores[lines] + + lines = 0 + line = H + for row in range(H, -1, -1): + count = 0 + for i in range(1, W+1): + i += 15 + if field_2[row][i]: + count += 1 + field_2[line][i] = field_2[row][i] + if count < W: + line -= 1 + else: + anim_speed_2 += 5 + lines += 1 + + score_2 += scores[lines] + + #draw grid + [pygame.draw.rect(screen, (40, 40, 40), i_rect, 1) for i_rect in grid] + #draw second grid + [pygame.draw.rect(screen, (40, 40, 40), i_rect, 1) for i_rect in grid_2] + #draw figure + for i in range(4): + figure_rect.x = figure[i].x * TILE + figure_rect.y = figure[i].y * TILE + pygame.draw.rect(screen, pygame.Color('white'), figure_rect) + + figure_rect.x = figure_2[i].x * TILE + figure_rect.y = figure_2[i].y * TILE + pygame.draw.rect(screen, pygame.Color('white'), figure_rect) + #draw field + for y, raw in enumerate(field_1): + for x, col in enumerate(raw): + if col: + figure_rect.x, figure_rect.y = x * TILE, y * TILE + pygame.draw.rect(screen, col, figure_rect) + + for y, raw in enumerate(field_2): + for x, col in enumerate(raw): + if col: + figure_rect.x, figure_rect.y = x * TILE, y * TILE + pygame.draw.rect(screen, col, figure_rect) + + font = pygame.font.SysFont(None, 68) + title_tetris = font.render('TETRIS', True, pygame.Color('white')) + title_score = font.render('SCORE:', True, pygame.Color('white')) + result_score_1 = font.render(str(score_1), True, pygame.Color('white')) + result_score_2 = font.render(str(score_2), True, pygame.Color('white')) + + sc.blit(title_tetris, (510, 50)) + sc.blit(title_tetris, (1180, 50)) + + sc.blit(title_score, (510, 800)) + sc.blit(title_score, (1180, 800)) + + sc.blit(result_score_1, (510, 850)) + sc.blit(result_score_2, (1180, 850)) + + #game over + for i in range(W+1): + if field_1[1][i]: + field_1 = [[0 for i in range(W+1)] for j in range(H+1)] + anim_count_1, anim_speed_1, anim_limit_1 = 0, 0, 0 + pygame.display.flip() + flag += 1 + + + for i in range(2*W+7-11, 2*W+7): + if field_2[1][i]: + field_2 = [[0 for i in range(2*W+7)] for j in range(H+1)] + anim_count_2, anim_speed_2, anim_limit_2 = 0, 0, 0 + pygame.display.flip() + flag += 1 + lock = 1 + + if flag == 2: + if score_1 > score_2: + result = "Bot 1 WIN" + elif score_1 < score_2: + if bot_user == 1: + result = "Bot 2 WIN" + if bot_user == 0: + result = "Player 2 WIN" + elif score_1 == score_2: + result = "DRAW" + + screen.fill(pygame.Color('black')) + title_result = font.render(result, True, pygame.Color('white')) + sc.blit(title_result, (800, 500)) + + pygame.display.flip() + clock.tick(FPS) + + +def main(): + pygame.init() + clock = pygame.time.Clock() + + RES = 1600, 1000 + screen = pygame.display.set_mode(RES) + W, H = 10, 20 + TILE = 45 + FPS = 60 + menu = pygame_menu.Menu('Welcome', 400, 310) + + bot(TILE, W, H, clock, FPS, screen, 0, menu) + + +if __name__=='__main__': + main() \ No newline at end of file