From ac3e8ee7685fde8a2bc1978ad424d83cff3fdba7 Mon Sep 17 00:00:00 2001 From: adrienmalin <41926238+adrienmalin@users.noreply.github.com> Date: Tue, 12 Feb 2019 18:46:40 +0100 Subject: [PATCH] combo, TAB, hundred separator --- README.md | 4 -- pyproject.toml | 2 +- terminis/terminis.py | 97 +++++++++++++++++++++++++++----------------- 3 files changed, 60 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index a71c590..3452858 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,3 @@ terminis [level] You can change keys by editing: * `%appdata%\Terminis\config.cfg` on Windows * `$XDG_CONFIG_HOME/Terminis/config.cfg` or `~/.config/Terminis/config.cfg` on Linux - -Acceptable values: -* printable characters (`q`, `*`, ` `...) -* curses's constants name starting with `KEY_` (see [Python documentation](https://docs.python.org/3/library/curses.html?highlight=curses#constants)) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 8d33643..78fc296 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "terminis" -version = "0.1.8" +version = "0.1.9" description = "Tetris clone for terminal. Ideal for servers without GUI!" authors = ["adrienmalin <41926238+adrienmalin@users.noreply.github.com>"] license = "MIT" diff --git a/terminis/terminis.py b/terminis/terminis.py index e691bd1..81735eb 100644 --- a/terminis/terminis.py +++ b/terminis/terminis.py @@ -12,6 +12,7 @@ import random import sched import time import os +import locale try: import configparser except ImportError: @@ -422,31 +423,39 @@ class Stats(Window): self.level = level - 1 self.goal = 0 self.score = 0 - self.load() + self.high_score = self.load_high_score() + self.combo = -1 self.time = time.time() self.lines_cleared = 0 self.clock_timer = None + self.strings = [] + locale.setlocale(locale.LC_ALL, '') Window.__init__(self, width, height, begin_x, begin_y) + self.new_level() - def load(self): + def load_high_score(self): try: with open(self.FILE_PATH, "r") as f: - self.high_score = int(f.read()) + return int(f.read()) except: - self.high_score = 0 + return 0 def refresh(self): self.draw_border() - self.window.addstr(2, 2, "SCORE\t%d" % self.score) + self.window.addstr(2, 2, "SCORE\t{:n}".format(self.score)) if self.score >= self.high_score: - self.window.addstr(3, 2, "HIGH\t%d" % self.high_score, curses.A_BLINK) + self.window.addstr(3, 2, "HIGH\t{:n}".format(self.high_score), curses.A_BLINK|curses.A_BOLD) else: - self.window.addstr(3, 2, "HIGH\t%d" % self.high_score) + self.window.addstr(3, 2, "HIGH\t{:n}".format(self.high_score)) t = time.localtime(time.time() - self.time) self.window.addstr(4, 2, "TIME\t%02d:%02d:%02d" % (t.tm_hour-1, t.tm_min, t.tm_sec)) self.window.addstr(5, 2, "LEVEL\t%d" % self.level) self.window.addstr(6, 2, "GOAL\t%d" % self.goal) self.window.addstr(7, 2, "LINES\t%d" % self.lines_cleared) + y0 = self.height - len(self.strings) - 2 + for y, string in enumerate(self.strings, start=y0): + x = (self.width-len(string)) // 2 + 1 + self.window.addstr(y, x, string) self.window.refresh() def clock(self): @@ -470,29 +479,32 @@ class Stats(Window): self.refresh() def piece_locked(self, nb_lines, t_spin): + self.strings = [] + if t_spin: + self.strings.append(t_spin) + if nb_lines: + self.strings.append(self.LINES_CLEARED_NAMES[nb_lines]) + self.combo += 1 + else: + self.combo = -1 if nb_lines or t_spin: self.lines_cleared += nb_lines - s = self.SCORES[nb_lines][t_spin] - self.goal -= s - s *= 100 * self.level - self.score += s - if self.score > self.high_score: - self.high_score = self.score - if nb_lines == 4 or (nb_lines and t_spin): - curses.beep() - if self.goal <= 0: - self.new_level() - else: - self.refresh() - x = (self.width-len(t_spin)) // 2 + 1 - self.window.addstr(self.height-5, x, t_spin) - name = self.LINES_CLEARED_NAMES[nb_lines] - x = (self.width-len(name)) // 2 + 1 - self.window.addstr(self.height-4, x, name) - s = str(s) - x = (self.width-len(s)) // 2 + 1 - self.window.addstr(self.height-3, x, s) - self.window.refresh() + ds = self.SCORES[nb_lines][t_spin] + self.goal -= ds + ds *= 100 * self.level + self.score += ds + self.strings.append(str(ds)) + if self.combo >= 1: + self.strings.append("COMBO x%d" % self.combo) + ds = (20 if nb_lines==1 else 50) * self.combo * self.level + self.score += ds + self.strings.append(str(ds)) + if nb_lines == 4 or (nb_lines and t_spin): + curses.beep() + if self.score > self.high_score: + self.high_score = self.score + if self.goal <= 0: + self.new_level() else: self.refresh() @@ -519,27 +531,26 @@ class Config(Window, configparser.SafeConfigParser): self.set("CONTROLS", "MOVE LEFT", "KEY_LEFT") self.set("CONTROLS", "MOVE RIGHT", "KEY_RIGHT") self.set("CONTROLS", "SOFT DROP", "KEY_DOWN") - self.set("CONTROLS", "HARD DROP", " ") + self.set("CONTROLS", "HARD DROP", "SPACE") self.set("CONTROLS", "ROTATE COUNTER", "KEY_UP") - self.set("CONTROLS", "ROTATE CLOCKWISE", "\n") + self.set("CONTROLS", "ROTATE CLOCKWISE", "ENTER") self.set("CONTROLS", "HOLD", "h") self.set("CONTROLS", "PAUSE", "p") self.set("CONTROLS", "QUIT", "q") if os.path.exists(self.FILE_PATH): self.read(self.FILE_PATH) - for action, key in self.items("CONTROLS"): - if key == "": - self.set("CONTROLS", action, " ") - elif key == "KEY_ENTER": - self.set("CONTROLS", action, "\n") else: if not os.path.exists(CONFIG_PATH): os.mkdir(CONFIG_PATH) try: with open(self.FILE_PATH, 'w') as f: f.write( -"""# Acceptable values are printable characters ("q", "*", " "...) and curses's constants name starting with "KEY_" -# See https://docs.python.org/3/library/curses.html?highlight=curses#constants +"""# You can change key below. +# Acceptable values are: +# * `SPACE`, `TAB`, `ENTER` +# * printable characters (`q`, `*`...) +# * curses's constants name starting with `KEY_` +# See https://docs.python.org/3/library/curses.html?highlight=curses#constants """ ) @@ -548,6 +559,13 @@ class Config(Window, configparser.SafeConfigParser): print("Configuration could not be saved:") print(e) Window.__init__(self, width, height, begin_x, begin_y) + for action, key in self.items("CONTROLS"): + if key == "SPACE": + self.set("CONTROLS", action, " ") + elif key == "ENTER": + self.set("CONTROLS", action, "\n") + elif key == "TAB": + self.set("CONTROLS", action, "\t") def refresh(self): self.draw_border() @@ -570,7 +588,10 @@ class Game: self.scr = scr if curses.has_colors(): self.init_colors() - curses.curs_set(0) + try: + curses.curs_set(0) + except curses.error: + pass self.scr.timeout(0) self.scr.getch() self.scheduler = sched.scheduler(time.time, self.process_input)