Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
2048
-
Fun game. I'm addicted.
Fwiw, I added swipes here , though I was starting from the version you posted, not the latest.
-
Thanks, I've merged your addition. :) I was wondering how hard that would be, I'm rather impressed at how easy it looks.
-
Would you mind if I took a stab at making the design closer to 2048's?
-
Techteej, if it would help, I made a version of 2048 for CPython a few months back, but I haven't tested it out on Pythonista, probably requires a little tweaking to get it to work.
<a href = "http://i.imgur.com/6QENQ3Y.png">Screenshot</a>
<a href = "https://gist.github.com/pyos/db31f5295afd20551d4e">Source</a>
-
That actually helps a lot, even though Im getting the colors through github then converting them the old fashioned way to Rgb.
-
Of course I wouldn't mind. :)
Mine does support different sizes, btw.
@LawAbidingCactus, what language is that? Doesn't look like Python.
-
@henryiii Almost finished, but I can't quite seem to get the color changing based on numbers. Which line would I find this on?
-
@techteej, I think you want line 110. That's where I set up the board after every move.
-
@henryiii thats the line, but when I change the color on that line, it forces all non-empty tile colors to change to that color.
-
@techteej You use the value of the tile to set the color. For example, make a dictionary or list of the colors you want, then set it based on the value 'lab'. If you need the the value as a number 0-11, that's how it is stored internally.
For example:
At the top:COLORS = ('white','blue', (0,1,1,1), ...) # Add 12 colors here, the first is empty cell
In the function:
simplelabel = board.traditional_data[i,j] labels[i,j].background_color = COLORS[simplelabel]
-
It would be cooler if this project was a repo on GitHub instead of a gist so that multiple folks could contribute code.
-
I get an IndexError: tuple index out of range.
-
Oops, don't use traditional_data. Replace that woth data. My bad. Data goes from 0-11. Traditional data is the printed number (2,4,8,...)
@ccc Agreed, but gistcheck is simple and easy to use from a menu. Is there something (not using shellista) for git? If there's a good library, I don't mind making a UI.
-
shellista has the best git support -- it is basically a wrapper around dulwich (there is some gittle in there, but I think you can do everything with dulwich.porcelain). If you look at the git stuff in shellista, it would not be hard to convert those scripts to be usable in the action menu.
-
I tried to implement a delay, but I'm not getting the results I would like to. Looks like I'll stick to making the design closer xD.
-
Quick tweak to ask the user how many tiles, x by x, the board should be:
""" Created on Sat Jul 12 09:33:29 2014 @author: henryii """ import console, random import numpy as np from functools import partial myBoard = int(input("Enter the number of tiles, x by x, you want the board to be: ")) size = myBoard COLORS = ((0.93333333333, 0.89411764705, 0.85490196078), (0.93333333333, 0.89411764705, 0.85490196078), (0.9294117647, 0.87843137254, 0.78431372549), (0.94901960784, 0.69411764705, 0.47450980392), (0.96078431372, 0.58431372549, 0.38823529411),(0.96470588235, 0.4862745098, 0.3725490196), (0.96470588235, 0.36862745098, 0.23137254902),(0.9294117647, 0.81176470588, 0.44705882352), (0.9294117647, 0.8, 0.38039215686),(0.9294117647, 0.78431372549, 0.31372549019), (0.9294117647, 0.7725490196, 0.24705882352), (0.9294117647, 0.76078431372, 0.18039215686),) # Add 12 colors here, the first is empty cell class Board (object): def __init__(self, data=np.zeros((size,size),dtype=int)): self.data = data def add_tile(self): data = self.data.reshape(-1) locs = np.nonzero(data == 0)[0] if len(locs): data[random.choice(locs)] = random.randint(1,2) return True return False def check_move(self): 'Checks to see if move available' if np.count_nonzero(self.data == 0): return True for row in self.data: if np.count_nonzero(np.ediff1d(row) == 0): return True for row in self.data.T: if np.count_nonzero(np.ediff1d(row) == 0): return True return False def __repr__(self): return self.__class__.__name__+ '(' +repr(self.data) + ')' def __str__(self): return str(self.traditional_data) + '\nScore: {}'.format(self.score) @property def traditional_data(self): data = 2**self.data data[data == 1] = 0 return data @property def score(self): return (self.traditional_data).sum() def move(self, dir, test = False): 'right,up,left,down as 0,1,2,3' made_move = False data = self.data if dir%2: data = data.T if (dir-1)//2 != 0: data = np.fliplr(data) for row in data: vals = row[row!=0] for n in range(len(vals)-1): if vals[n]==vals[n+1]: vals[n]+=1 vals[n+1]=0 vals = vals[vals!=0] vals.resize(row.shape) made_move |= not np.all(vals == row) if not test: row[:] = vals return made_move def directions(self): return {x for x in range(4) if self.move(x,True)} def auto_simple(self, pattern=(0,1,2,3)): for d in pattern: if self.move(d): return True return False def run_console(): board = Board() board.add_tile() while True: print board x = raw_input('wasd:').lower() if len(x)==1 and x in 'wasd': v = 'dwas'.find(x) if board.move(v): board.add_tile() if not board.check_move(): console.hud_alert('Game over.', 'error', 2.5) break else: break print 'Done' return board def _ui_setup(board, labels, v): for i in range(board.data.shape[0]): for j in range(board.data.shape[1]): lab = board.traditional_data[i,j] simplelabel = board.data[i,j] labels[i,j].background_color = COLORS[simplelabel] labels[i,j].text = str(lab) if lab else '' #labels[i,j].background_color = (0.9294117647, 0.76078431372, 0.18039215686) if lab else (0.93333333333, 0.89411764705, 0.85490196078) v.name = 'Score: {}'.format(board.score) def _ui_move(board, labels, v, dir, buts, sender): if board.move(dir): board.add_tile() if not board.check_move(): console.hud_alert('Game over.', 'error', 2.5) v.close() _ui_setup(board, labels, v) _setup_buts(board, buts) def _ui_move_auto(board, labels, v, buts, sender): if board.auto_simple(): board.add_tile() if not board.check_move(): console.hud_alert('Game over.', 'error', 2.5) v.close() _ui_setup(board, labels, v) _setup_buts(board, buts) def _setup_buts(board,buts): valid_dirs = board.directions() for d in range(4): buts[d].enabled = d in valid_dirs def run_ui(): import ui class MyView(ui.View): moves=[None for i in range(4)] #list containing function handles old=np.array((0,0)) #old touch location def touch_began(self, touch): # Called when a touch begins. store old location self.old[:]=touch.location def touch_ended(self, touch): # Called when a touch ends. # compute vector from old to new touch u=np.array(touch.location)-self.old # first, determine whether x or y moved the most if abs(u[0])>abs(u[1]): dir=0 else: dir=1 # then, determine sign if u[dir]>0: dir+=2 if dir else 0 else: dir+=0 if dir else 2 # call the appropriate move function if u[0]**2 + u[1]**2 > 30**2: self.moves[dir](self) v = MyView(frame=(0,0,100,140)) v.background_color = (0.98039215686, 0.9725490196, 0.93725490196) board=Board() board.add_tile() labels = np.empty_like(board.data,dtype=object) for i in range(board.data.shape[0]): for j in range(board.data.shape[1]): labels[i,j] = ui.Label() labels[i,j].flex = 'HWLRTB' labels[i,j].alignment = ui.ALIGN_CENTER labels[i,j].border_width = 1 labels[i,j].corner_radius = 2 labels[i,j].font = ('<system-bold>',24) labels[i,j].frame = ( 100/board.data.shape[1]*(j+.04), 100/board.data.shape[0]*(i+.04), 100/board.data.shape[1]*.92, 100/board.data.shape[0]*.92) v.add_subview(labels[i,j]) _ui_setup(board,labels,v) buts = [] for i in range(4): but = ui.Button() but.title = ('RIGHT','UP','LEFT','DOWN')[i] but.frame = ((60,110,20,20), (40,100,20,20), (20,110,20,20), (40,120,20,20))[i] but.flex = 'WHTBLR' but.action = partial(_ui_move,board,labels,v,i,buts) v.add_subview(but) v.moves[i]=but.action #to allow swipes buts.append(but) but = ui.ButtonItem() but.title = 'Auto Move' but.action = partial(_ui_move_auto,board,labels,v,buts) v.right_button_items = [but] _setup_buts(board,buts) v.present() if __name__ == '__main__': #self = run_console() run_ui()</code>```
-
I apologize for the poorly posted code.... If anyone can fix it, can they please notify me of it?
-
I'll be merging changes tomorrow, if I have time. Thanks! Did you surround the code with three backticks (`)? See github style fenced code.
-
Updated, combined everyone's work so far, plus a few clean ups. I implemented a slightly nicer size dialog (but it currently won't run unmodified on a PC).
-
A crucial feature of the original and also of the kivy-python implementation of this game is that when you quickly swipe in a direction and then in the opposite direction, then numbers are NOT added both times, only after the second swipe. This allows keeping the largest number in a corner at ALL times. With this strategy and some practice it is easy to reach 4096 or even 8192.