概述
作者这几天去一趟湖南,这快车真“快”啊,跨越3个省需要接近一天时间。。。坐火车实在无聊就去玩2048,结果一遍一遍的手滑失误,导致心态爆炸。想了想干脆自己做个2048算了,顺便还可以写外挂上分!
Python Code
MainWindow:
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 ''' 4 Created on Mar 24, 2017 5 6 @author: zhengli 7 ''' 8 9 import copy 10 import numpy 11 from PyQt5.QtCore import Qt 12 from PyQt5.QtGui import (QIcon, QFont) 13 from PyQt5.QtWidgets import (QAction, QDesktopWidget, QGridLayout, QMainWindow, QMessageBox, QToolTip, QWidget) 14 import GameCanvas 15 16 17 class App(QMainWindow): 18 """ 19 Main Window. 20 """ 21 22 # noinspection PyArgumentList 23 def __init__(self): 24 25 QMainWindow.__init__(self) 26 27 # noinspection PyCallByClass,PyTypeChecker 28 QToolTip.setFont(QFont('SansSerif', 10)) 29 self.setGeometry(100, 100, 600, 600) 30 self.frameGeometry().moveCenter(QDesktopWidget().availableGeometry().center()) 31 self.move(self.frameGeometry().topLeft()) 32 self.setWindowTitle('2048') 33 self.setWindowIcon(QIcon('python.png')) 34 self.setWindowFlags(Qt.WindowStaysOnTopHint) 35 36 self.action = dict() 37 self.actionLoad() 38 self.menuBarLoad() 39 40 self.data = dict() 41 self.canvas = 0 42 self.gameImage(4, 4) 43 44 self.statusBar().showMessage('Ready') 45 46 self.show() 47 48 def actionLoad(self): 49 """ 50 set MainData.action 51 """ 52 self.action["4X4"] = QAction('4X4', self) 53 self.action["4X4"].setShortcut('Ctrl+4') 54 self.action["4X4"].setStatusTip('4X4 game') 55 self.action["4X4"].triggered.connect(lambda: self.gameImage(4, 4)) 56 57 self.action["5X5"] = QAction('5X5', self) 58 self.action["5X5"].setShortcut('Ctrl+5') 59 self.action["5X5"].setStatusTip('5X5 game') 60 self.action["5X5"].triggered.connect(lambda: self.gameImage(5, 5)) 61 62 self.action["6X6"] = QAction('6X6', self) 63 self.action["6X6"].setShortcut('Ctrl+6') 64 self.action["6X6"].setStatusTip('6X6 game') 65 self.action["6X6"].triggered.connect(lambda: self.gameImage(6, 6)) 66 67 def menuBarLoad(self): 68 """ 69 set MainWindow.menuBar 70 """ 71 self.statusBar() 72 menubar = self.menuBar() 73 74 gameMenu = menubar.addMenu('&Game') 75 gameMenu.addAction(self.action["4X4"]) 76 gameMenu.addAction(self.action["5X5"]) 77 gameMenu.addAction(self.action["6X6"]) 78 79 def gameImage(self, m, n): 80 """ 81 image draw. 82 """ 83 # noinspection PyBroadException 84 try: 85 data = self.data["%d_%d" % (m, n)] 86 count = self.data["score_%d_%d" % (m, n)] 87 except: 88 self.data["%d_%d" % (m, n)] = numpy.zeros((m, n), dtype=int) 89 data = self.data["%d_%d" % (m, n)] 90 self.data["score_%d_%d" % (m, n)] = 0 91 count = self.data["score_%d_%d" % (m, n)] 92 self.statusBar().showMessage('Score: %d' % count) 93 94 layout = QGridLayout() 95 layout.setSpacing(10) 96 97 widget = QWidget() 98 self.canvas = GameCanvas.GameCanvas(data=data, count=count, parent=widget) 99 self.canvas.fig.canvas.mpl_connect('button_press_event', self.button_press) 100 self.canvas.fig.canvas.mpl_connect('button_release_event', self.button_release) 101 102 layout.addWidget(self.canvas) 103 widget.setLayout(layout) 104 self.setCentralWidget(widget) 105 106 def button_press(self, event): 107 """ 108 Get coordinates 109 """ 110 self.canvas.event_x = event.x 111 self.canvas.event_y = event.y 112 113 # noinspection PyUnresolvedReferences 114 def button_release(self, event): 115 """ 116 :param event: 117 :return: 118 """ 119 data_backup = copy.deepcopy(self.canvas.data) 120 if abs(self.canvas.event_x - event.x) > abs(self.canvas.event_y - event.y): 121 if event.x > self.canvas.event_x: 122 self.canvas.right_operation(data_backup=data_backup) 123 else: 124 self.canvas.left_operation(data_backup=data_backup) 125 else: 126 if event.y > self.canvas.event_y: 127 self.canvas.up_operation(data_backup=data_backup) 128 else: 129 self.canvas.down_operation(data_backup=data_backup) 130 131 self.canvas.fig.clf() 132 self.canvas.axes = self.canvas.fig.add_axes([0, 0, 1, 1], frameon=False) 133 self.canvas.complete_draw() 134 self.canvas.fig.canvas.draw() 135 136 self.data["score_%d_%d" % (self.canvas.m, self.canvas.n)] = self.canvas.count 137 self.statusBar().showMessage('Score: %d' % self.canvas.count) 138 139 # noinspection PyUnresolvedReferences 140 def keyPressEvent(self, event): 141 """ 142 :param event: 143 :return: 144 """ 145 data_backup = copy.deepcopy(self.canvas.data) 146 if event.key() == Qt.Key_Right: 147 self.canvas.right_operation(data_backup=data_backup) 148 elif event.key() == Qt.Key_Left: 149 self.canvas.left_operation(data_backup=data_backup) 150 elif event.key() == Qt.Key_Up: 151 self.canvas.up_operation(data_backup=data_backup) 152 elif event.key() == Qt.Key_Down: 153 self.canvas.down_operation(data_backup=data_backup) 154 elif event.key() == Qt.Key_Escape: 155 self.canvas.data *= 0 156 self.canvas.count = 0 157 elif event.key() == Qt.Key_Delete: 158 print("yes ") 159 160 self.canvas.fig.clf() 161 self.canvas.axes = self.canvas.fig.add_axes([0, 0, 1, 1], frameon=False) 162 self.canvas.complete_draw() 163 self.canvas.fig.canvas.draw() 164 165 self.data["score_%d_%d" % (self.canvas.m, self.canvas.n)] = self.canvas.count 166 self.statusBar().showMessage('Score: %d' % self.canvas.count) 167 168 def closeEvent(self, event): 169 """ 170 exit game. 171 """ 172 # noinspection PyCallByClass,PyTypeChecker 173 reply = QMessageBox.question(self, 'Message', "Are you sure to quit?", 174 QMessageBox.Yes | QMessageBox.No, QMessageBox.No) 175 if reply == QMessageBox.Yes: 176 event.accept() 177 else: 178 event.ignore()
GameImage:
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 ''' 4 Created on Mar 24, 2017 5 6 @author: zhengli 7 ''' 8 9 import copy 10 import random 11 import numpy 12 from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg 13 from matplotlib.figure import Figure 14 from matplotlib import collections 15 16 17 class GameCanvas(FigureCanvasQTAgg): 18 """ 19 basic data 20 """ 21 22 def __init__(self, data=None, count=0, parent=None, width=5, height=4, dpi=100): 23 24 self.data = data 25 self.count = count 26 self.m = len(data) 27 self.n = len(data[0]) 28 29 self.event_x = 0 30 self.event_y = 0 31 32 self.fig = Figure(figsize=(width, height), dpi=dpi) 33 self.axes = self.fig.add_axes([0, 0, 1, 1], frameon=False) 34 self.complete_draw() 35 36 FigureCanvasQTAgg.__init__(self, self.fig) 37 self.setParent(parent) 38 39 def complete_draw(self): 40 """ 41 :return: 42 """ 43 shape = numpy.array([[0.05, 0.05], [0.05, 0.95], [0.95, 0.95], [0.95, 0.05]]) 44 for i in range(self.m): 45 for j in range(self.n): 46 rectangle = copy.deepcopy(shape) 47 rectangle[:, 0] += j 48 rectangle[:, 1] += self.m - i 49 if 0.1 * numpy.log2(max(2, 2 * self.data[i][j])) < 1: 50 alpha = 0.1 * numpy.log2(max(2, 2 * self.data[i][j])) 51 else: 52 alpha = 1 53 patch = collections.PolyCollection([rectangle], alpha=alpha) 54 self.axes.add_collection(patch) 55 if self.data[i][j] != 0: 56 self.axes.text(j + 0.5, self.m - i + 0.5, s=str(self.data[i][j]), color='white', fontsize=45, 57 horizontalalignment='center', verticalalignment='center') 58 self.axes.autoscale() 59 60 def right_operation(self, data_backup): 61 """ 62 :param data_backup: 63 :return: 64 """ 65 for i in range(self.m): 66 index, = numpy.where(self.data[i, :] != 0) 67 if len(index) != 0: 68 values = self.data[i, index] 69 if len(index) > 1: 70 j = len(values) - 1 71 while j != 0: 72 if values[j] == values[j - 1]: 73 self.count += values[j - 1] 74 values[j - 1] *= 2 75 values = numpy.hstack((values[:j], values[(j + 1):])) 76 break 77 else: 78 j -= 1 79 self.data[i, :] *= 0 80 for j in range(len(values)): 81 self.data[i][-j - 1] = values[-j - 1] 82 if self.data.min() * (self.data - data_backup).min() == 0: 83 index, = numpy.where(self.data[:, 0] == 0) 84 if len(index) != 0: 85 i = index[random.randint(1, len(index)) - 1] 86 self.data[i][0] = random.randint(1, 2) 87 88 def left_operation(self, data_backup): 89 """ 90 :param data_backup: 91 :return: 92 """ 93 for i in range(self.m): 94 index, = numpy.where(self.data[i, :] != 0) 95 if len(index) != 0: 96 values = self.data[i, index] 97 if len(index) > 1: 98 j = 0 99 while j != len(values) - 1: 100 if values[j] == values[j + 1]: 101 self.count += values[j + 1] 102 values[j + 1] *= 2 103 values = numpy.hstack((values[:j], values[(j + 1):])) 104 break 105 else: 106 j += 1 107 self.data[i, :] *= 0 108 for j in range(len(values)): 109 self.data[i][j] = values[j] 110 if self.data.min() * (self.data - data_backup).min() == 0: 111 index, = numpy.where(self.data[:, -1] == 0) 112 if len(index) != 0: 113 i = index[random.randint(1, len(index)) - 1] 114 self.data[i][-1] = random.randint(1, 2) 115 116 def up_operation(self, data_backup): 117 """ 118 :param data_backup: 119 :return: 120 """ 121 for j in range(self.n): 122 index, = numpy.where(self.data[:, j] != 0) 123 if len(index) != 0: 124 values = self.data[index, j] 125 if len(index) > 1: 126 i = 0 127 while i != len(values) - 1: 128 if values[i] == values[i + 1]: 129 self.count += values[i + 1] 130 values[i + 1] *= 2 131 values = numpy.hstack((values[:i], values[(i + 1):])) 132 break 133 else: 134 i += 1 135 self.data[:, j] *= 0 136 for i in range(len(values)): 137 self.data[i][j] = values[i] 138 if self.data.min() * (self.data - data_backup).min() == 0: 139 index, = numpy.where(self.data[-1, :] == 0) 140 if len(index) != 0: 141 j = index[random.randint(1, len(index)) - 1] 142 self.data[-1][j] = random.randint(1, 2) 143 144 def down_operation(self, data_backup): 145 """ 146 :param data_backup: 147 :return: 148 """ 149 for j in range(self.n): 150 index, = numpy.where(self.data[:, j] != 0) 151 if len(index) != 0: 152 values = self.data[index, j] 153 if len(index) > 1: 154 i = len(values) - 1 155 while i != 0: 156 if values[i] == values[i - 1]: 157 self.count += values[i - 1] 158 values[i - 1] *= 2 159 values = numpy.hstack((values[:i], values[(i + 1):])) 160 break 161 else: 162 i -= 1 163 self.data[:, j] *= 0 164 for i in range(len(values)): 165 self.data[-i - 1][j] = values[-i - 1] 166 if self.data.min() * (self.data - data_backup).min() == 0: 167 index, = numpy.where(self.data[0, :] == 0) 168 if len(index) != 0: 169 j = index[random.randint(1, len(index)) - 1] 170 self.data[0][j] = random.randint(1, 2)
Start:
1 #!/usr/bin/python 2 # -*- coding:utf-8 -*- 3 ''' 4 Created on Mar 24, 2017 5 6 @author: zhengli 7 ''' 8 9 import MainWindow 10 import sys 11 from PyQt5.QtWidgets import QApplication 12 13 if __name__ == '__main__': 14 app = QApplication(sys.argv) 15 ex = MainWindow.App() 16 sys.exit(app.exec_())
Demo
鼠标操作:
键盘操作:
声明
本文由“Hamilton算符”原创,未经博主允许不得转载!