diff --git a/.gitignore b/.gitignore index 8c8ba6a..430f6a9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ .vscode/settings.json # python -*.pyc \ No newline at end of file +*.pyc + +# config +config.json \ No newline at end of file diff --git a/README.md b/README.md index 768aa5c..f322382 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ 2048-python =========== +[![Run on Repl.it](https://repl.it/badge/github/yangshun/2048-python)](https://repl.it/github/yangshun/2048-python) + Based on the popular game [2048](https://github.com/gabrielecirulli/2048) by Gabriele Cirulli. The game's objective is to slide numbered tiles on a grid to combine them to create a tile with the number 2048. Here is a Python version that uses TKinter! ![screenshot](img/screenshot.png) @@ -9,9 +11,18 @@ To start the game, run: $ python3 puzzle.py +How to configure 2048-Python +== +After running puzzle.py, a json file called config.json will be created, in this file you will be able to configure 2048-Python. + +You can change the controls by changing "default" in line 1 of config.json to your prefered control scheme. + +Current control schemes: default (wasd), qwerty (wasd), azerty (zqsd), vim (khjl) + +To add a new control scheme edit constants.py and go to lines 28-32. Format is "name":"controls". Contributors: == -- [Tay Yang Shun](http://github.com/yangshun) +- [Yanghun Tay](http://github.com/yangshun) - [Emmanuel Goh](http://github.com/emman27) diff --git a/config.py b/config.py new file mode 100644 index 0000000..31bfed9 --- /dev/null +++ b/config.py @@ -0,0 +1,26 @@ +import json + +DEFAULT_CONFIG = { + "keylayout": 'default' +} + +global config +try: + with open("./config.json") as fp: + config = json.load(fp) +except: + try: + with open("./config.json", "w") as fp: + json.dump(DEFAULT_CONFIG, fp) + except: + pass + config = DEFAULT_CONFIG + +def get_config_option(key): + if key in config.keys(): + return config[key] + else: + return None + +# controls options are: default (wasd), azerty (zqsd) +# other control options must be added manually in constants.py diff --git a/constants.py b/constants.py index 86b550f..4b6834a 100644 --- a/constants.py +++ b/constants.py @@ -1,3 +1,4 @@ +import config SIZE = 400 GRID_LEN = 4 GRID_PADDING = 10 @@ -23,18 +24,31 @@ FONT = ("Verdana", 40, "bold") -KEY_UP_ALT = "\'\\uf700\'" -KEY_DOWN_ALT = "\'\\uf701\'" -KEY_LEFT_ALT = "\'\\uf702\'" -KEY_RIGHT_ALT = "\'\\uf703\'" - -KEY_UP = "'w'" -KEY_DOWN = "'s'" -KEY_LEFT = "'a'" -KEY_RIGHT = "'d'" -KEY_BACK = "'b'" - -KEY_J = "'j'" -KEY_K = "'k'" -KEY_L = "'l'" -KEY_H = "'h'" +# controls +presets = { + "default": "wasd", + "azerty": "zqsd", + "qwerty": "wasd", + "vim": "khjl" +} + +keylayout = config.get_config_option("keylayout") + +if keylayout in presets.keys(): + KEY_UP = "'"+presets[keylayout][0]+"'" + KEY_DOWN = "'"+presets[keylayout][2]+"'" + KEY_LEFT = "'"+presets[keylayout][1]+"'" + KEY_RIGHT = "'"+presets[keylayout][3]+"'" +elif len(keylayout) == 4: + KEY_UP = "'"+keylayout[0]+"'" + KEY_DOWN = "'"+keylayout[2]+"'" + KEY_LEFT = "'"+keylayout[1]+"'" + KEY_RIGHT = "'"+keylayout[3]+"'" + KEY_BACK = "'b'" +else: + KEY_UP = "'w'" + KEY_DOWN = "'s'" + KEY_LEFT = "'a'" + KEY_RIGHT = "'d'" + +KEY_BACK = "'b'" \ No newline at end of file diff --git a/logic.py b/logic.py index 7b6fb1e..80c3024 100644 --- a/logic.py +++ b/logic.py @@ -163,7 +163,6 @@ def merge(mat): def up(game): - print("up") # return matrix after shifting up game = transpose(game) game, done = cover_up(game) @@ -176,7 +175,6 @@ def up(game): def down(game): - print("down") game = reverse(transpose(game)) game, done = cover_up(game) temp = merge(game) @@ -188,7 +186,6 @@ def down(game): def left(game): - print("left") # return matrix after shifting left game, done = cover_up(game) temp = merge(game) @@ -199,7 +196,6 @@ def left(game): def right(game): - print("right") # return matrix after shifting right game = reverse(game) game, done = cover_up(game) diff --git a/puzzle.py b/puzzle.py index 46773a5..c130987 100644 --- a/puzzle.py +++ b/puzzle.py @@ -1,9 +1,10 @@ import random -from tkinter import Frame, Label, CENTER +import tkinter as tk +from tkinter import Frame, Label, CENTER, messagebox import logic import constants as c - +import config class GameGrid(Frame): def __init__(self): @@ -15,17 +16,13 @@ def __init__(self): # self.gamelogic = gamelogic self.commands = {c.KEY_UP: logic.up, c.KEY_DOWN: logic.down, - c.KEY_LEFT: logic.left, c.KEY_RIGHT: logic.right, - c.KEY_UP_ALT: logic.up, c.KEY_DOWN_ALT: logic.down, - c.KEY_LEFT_ALT: logic.left, c.KEY_RIGHT_ALT: logic.right, - c.KEY_H: logic.left, c.KEY_L: logic.right, - c.KEY_K: logic.up, c.KEY_J: logic.down} + c.KEY_LEFT: logic.left, c.KEY_RIGHT: logic.right} self.grid_cells = [] self.init_grid() self.init_matrix() self.update_grid_cells() - + self.mainloop() def init_grid(self): @@ -70,7 +67,6 @@ def update_grid_cells(self): new_number), bg=c.BACKGROUND_COLOR_DICT[new_number], fg=c.CELL_COLOR_DICT[new_number]) self.update_idletasks() - def key_down(self, event): key = repr(event.char) if key == c.KEY_BACK and len(self.history_matrixs) > 1: @@ -85,17 +81,14 @@ def key_down(self, event): self.history_matrixs.append(self.matrix) self.update_grid_cells() done = False - if logic.game_state(self.matrix) == 'win': - self.grid_cells[1][1].configure( - text="You", bg=c.BACKGROUND_COLOR_CELL_EMPTY) - self.grid_cells[1][2].configure( - text="Win!", bg=c.BACKGROUND_COLOR_CELL_EMPTY) if logic.game_state(self.matrix) == 'lose': - self.grid_cells[1][1].configure( - text="You", bg=c.BACKGROUND_COLOR_CELL_EMPTY) - self.grid_cells[1][2].configure( - text="Lose!", bg=c.BACKGROUND_COLOR_CELL_EMPTY) - + retry = messagebox.askyesno("You Lost!", "Do you want to reset the game?") + if retry == True: + print('New Game!') + self.destroy() + GameGrid() + if retry == False: + exit() def generate_next(self): index = (self.gen(), self.gen()) while self.matrix[index[0]][index[1]] != 0: