Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
201
Task/2048/Python/2048-1.py
Normal file
201
Task/2048/Python/2048-1.py
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import curses
|
||||
from random import randrange, choice # generate and place new tile
|
||||
from collections import defaultdict
|
||||
|
||||
letter_codes = [ord(ch) for ch in 'WASDRQwasdrq']
|
||||
actions = ['Up', 'Left', 'Down', 'Right', 'Restart', 'Exit']
|
||||
actions_dict = dict(zip(letter_codes, actions * 2))
|
||||
|
||||
def get_user_action(keyboard):
|
||||
char = "N"
|
||||
while char not in actions_dict:
|
||||
char = keyboard.getch()
|
||||
return actions_dict[char]
|
||||
|
||||
def transpose(field):
|
||||
return [list(row) for row in zip(*field)]
|
||||
|
||||
def invert(field):
|
||||
return [row[::-1] for row in field]
|
||||
|
||||
class GameField(object):
|
||||
def __init__(self, height=4, width=4, win=2048):
|
||||
self.height = height
|
||||
self.width = width
|
||||
self.win_value = win
|
||||
self.score = 0
|
||||
self.highscore = 0
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
if self.score > self.highscore:
|
||||
self.highscore = self.score
|
||||
self.score = 0
|
||||
self.field = [[0 for i in range(self.width)] for j in range(self.height)]
|
||||
self.spawn()
|
||||
self.spawn()
|
||||
|
||||
def move(self, direction):
|
||||
def move_row_left(row):
|
||||
def tighten(row): # squeese non-zero elements together
|
||||
new_row = [i for i in row if i != 0]
|
||||
new_row += [0 for i in range(len(row) - len(new_row))]
|
||||
return new_row
|
||||
|
||||
def merge(row):
|
||||
pair = False
|
||||
new_row = []
|
||||
for i in range(len(row)):
|
||||
if pair:
|
||||
new_row.append(2 * row[i])
|
||||
self.score += 2 * row[i]
|
||||
pair = False
|
||||
else:
|
||||
if i + 1 < len(row) and row[i] == row[i + 1]:
|
||||
pair = True
|
||||
new_row.append(0)
|
||||
else:
|
||||
new_row.append(row[i])
|
||||
assert len(new_row) == len(row)
|
||||
return new_row
|
||||
return tighten(merge(tighten(row)))
|
||||
|
||||
moves = {}
|
||||
moves['Left'] = lambda field: \
|
||||
[move_row_left(row) for row in field]
|
||||
moves['Right'] = lambda field: \
|
||||
invert(moves['Left'](invert(field)))
|
||||
moves['Up'] = lambda field: \
|
||||
transpose(moves['Left'](transpose(field)))
|
||||
moves['Down'] = lambda field: \
|
||||
transpose(moves['Right'](transpose(field)))
|
||||
|
||||
if direction in moves:
|
||||
if self.move_is_possible(direction):
|
||||
self.field = moves[direction](self.field)
|
||||
self.spawn()
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
def is_win(self):
|
||||
return any(any(i >= self.win_value for i in row) for row in self.field)
|
||||
|
||||
def is_gameover(self):
|
||||
return not any(self.move_is_possible(move) for move in actions)
|
||||
|
||||
def draw(self, screen):
|
||||
help_string1 = '(W)Up (S)Down (A)Left (D)Right'
|
||||
help_string2 = ' (R)Restart (Q)Exit'
|
||||
gameover_string = ' GAME OVER'
|
||||
win_string = ' YOU WIN!'
|
||||
def cast(string):
|
||||
screen.addstr(string + '\n')
|
||||
|
||||
def draw_hor_separator():
|
||||
top = '┌' + ('┬──────' * self.width + '┐')[1:]
|
||||
mid = '├' + ('┼──────' * self.width + '┤')[1:]
|
||||
bot = '└' + ('┴──────' * self.width + '┘')[1:]
|
||||
separator = defaultdict(lambda: mid)
|
||||
separator[0], separator[self.height] = top, bot
|
||||
if not hasattr(draw_hor_separator, "counter"):
|
||||
draw_hor_separator.counter = 0
|
||||
cast(separator[draw_hor_separator.counter])
|
||||
draw_hor_separator.counter += 1
|
||||
|
||||
def draw_row(row):
|
||||
cast(''.join('│{: ^5} '.format(num) if num > 0 else '| ' for num in row) + '│')
|
||||
|
||||
screen.clear()
|
||||
cast('SCORE: ' + str(self.score))
|
||||
if 0 != self.highscore:
|
||||
cast('HIGHSCORE: ' + str(self.highscore))
|
||||
for row in self.field:
|
||||
draw_hor_separator()
|
||||
draw_row(row)
|
||||
draw_hor_separator()
|
||||
if self.is_win():
|
||||
cast(win_string)
|
||||
else:
|
||||
if self.is_gameover():
|
||||
cast(gameover_string)
|
||||
else:
|
||||
cast(help_string1)
|
||||
cast(help_string2)
|
||||
|
||||
def spawn(self):
|
||||
new_element = 4 if randrange(100) > 89 else 2
|
||||
(i,j) = choice([(i,j) for i in range(self.width) for j in range(self.height) if self.field[i][j] == 0])
|
||||
self.field[i][j] = new_element
|
||||
|
||||
def move_is_possible(self, direction):
|
||||
def row_is_left_movable(row):
|
||||
def change(i): # true if there'll be change in i-th tile
|
||||
if row[i] == 0 and row[i + 1] != 0: # Move
|
||||
return True
|
||||
if row[i] != 0 and row[i + 1] == row[i]: # Merge
|
||||
return True
|
||||
return False
|
||||
return any(change(i) for i in range(len(row) - 1))
|
||||
|
||||
check = {}
|
||||
check['Left'] = lambda field: \
|
||||
any(row_is_left_movable(row) for row in field)
|
||||
|
||||
check['Right'] = lambda field: \
|
||||
check['Left'](invert(field))
|
||||
|
||||
check['Up'] = lambda field: \
|
||||
check['Left'](transpose(field))
|
||||
|
||||
check['Down'] = lambda field: \
|
||||
check['Right'](transpose(field))
|
||||
|
||||
if direction in check:
|
||||
return check[direction](self.field)
|
||||
else:
|
||||
return False
|
||||
|
||||
def main(stdscr):
|
||||
curses.use_default_colors()
|
||||
game_field = GameField(win=32)
|
||||
state_actions = {} # Init, Game, Win, Gameover, Exit
|
||||
def init():
|
||||
game_field.reset()
|
||||
return 'Game'
|
||||
|
||||
state_actions['Init'] = init
|
||||
|
||||
def not_game(state):
|
||||
game_field.draw(stdscr)
|
||||
action = get_user_action(stdscr)
|
||||
responses = defaultdict(lambda: state)
|
||||
responses['Restart'], responses['Exit'] = 'Init', 'Exit'
|
||||
return responses[action]
|
||||
|
||||
state_actions['Win'] = lambda: not_game('Win')
|
||||
state_actions['Gameover'] = lambda: not_game('Gameover')
|
||||
|
||||
def game():
|
||||
game_field.draw(stdscr)
|
||||
action = get_user_action(stdscr)
|
||||
if action == 'Restart':
|
||||
return 'Init'
|
||||
if action == 'Exit':
|
||||
return 'Exit'
|
||||
if game_field.move(action): # move successful
|
||||
if game_field.is_win():
|
||||
return 'Win'
|
||||
if game_field.is_gameover():
|
||||
return 'Gameover'
|
||||
return 'Game'
|
||||
|
||||
state_actions['Game'] = game
|
||||
|
||||
state = 'Init'
|
||||
while state != 'Exit':
|
||||
state = state_actions[state]()
|
||||
|
||||
curses.wrapper(main)
|
||||
294
Task/2048/Python/2048-2.py
Normal file
294
Task/2048/Python/2048-2.py
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
''' Python 3.6.5 code using Tkinter graphical user interface.
|
||||
Option to set goal to powers of 2 from 128 to 2048. '''
|
||||
from tkinter import *
|
||||
from tkinter import messagebox
|
||||
from tkinter import ttk
|
||||
import random
|
||||
|
||||
# ************************************************
|
||||
|
||||
class Board:
|
||||
|
||||
def __init__(self):
|
||||
self.bd = ['']* 16
|
||||
self.goal = 2048
|
||||
self.choices = '2222222224'
|
||||
|
||||
# place 2 random squares on empty board:
|
||||
def place_two(self):
|
||||
idx = range(15)
|
||||
a, b = random.sample(idx, 2)
|
||||
self.bd[a] = random.choice(self.choices)
|
||||
self.bd[b] = random.choice(self.choices)
|
||||
|
||||
# return text on square at index=idx of board:
|
||||
def get_text(self, idx):
|
||||
return self.bd[idx]
|
||||
|
||||
# move squares on board based on arrow key entered:
|
||||
def move_squares(self, key):
|
||||
if key in ('LR'):
|
||||
# generate 4x4 2D array for row processing:
|
||||
rows = [[self.bd[0], self.bd[1], self.bd[2], self.bd[3]],
|
||||
[self.bd[4], self.bd[5], self.bd[6], self.bd[7]],
|
||||
[self.bd[8], self.bd[9], self.bd[10], self.bd[11]],
|
||||
[self.bd[12], self.bd[13], self.bd[14], self.bd[15]]]
|
||||
else:
|
||||
# generate transposed 4x4 2D array instead:
|
||||
rows = [[self.bd[0], self.bd[4], self.bd[8], self.bd[12]],
|
||||
[self.bd[1], self.bd[5], self.bd[9], self.bd[13]],
|
||||
[self.bd[2], self.bd[6], self.bd[10], self.bd[14]],
|
||||
[self.bd[3], self.bd[7], self.bd[11], self.bd[15]]]
|
||||
|
||||
# build a new 4x4 array of "moved" rows:
|
||||
nrows = []
|
||||
for row in rows:
|
||||
if key in 'RD':
|
||||
# reverse these rows and slide to left:
|
||||
row = row[::-1]
|
||||
nrow = self.slide_squares(row)
|
||||
if key in 'RD':
|
||||
# restore reversed rows:
|
||||
nrow = nrow[::-1]
|
||||
nrows.append(nrow)
|
||||
if key in ('UD'):
|
||||
# transpose arrays that were transposed:
|
||||
nrows = list(map(list, zip(*nrows)))
|
||||
|
||||
# flatten 4x4 2D array:
|
||||
newbd = []
|
||||
for row in nrows:
|
||||
for r in row:
|
||||
newbd.append(r)
|
||||
|
||||
# place a '2' or '4' in random open square of newbd:
|
||||
if newbd != self.bd and '' in newbd:
|
||||
loi = []
|
||||
for i in range(16):
|
||||
if newbd[i] == '':
|
||||
loi.append(i)
|
||||
i = random.choice(loi)
|
||||
newbd[i] = random.choice(self.choices)
|
||||
|
||||
self.bd = newbd
|
||||
return
|
||||
|
||||
# slide squares in row to the left:
|
||||
def slide_squares(self, row):
|
||||
new = [''] * 4
|
||||
icmb = -1
|
||||
inew = 0
|
||||
for x in row:
|
||||
if x:
|
||||
if (inew > 0 and
|
||||
x == new[inew-1] and
|
||||
icmb != inew-1):
|
||||
new[inew-1] = str(2*int(x))
|
||||
icmb = inew-1
|
||||
else:
|
||||
new[inew] = x
|
||||
inew += 1
|
||||
return new
|
||||
|
||||
# check if game won, lost, or continuing:
|
||||
def is_end(self):
|
||||
if self.goal in self.bd:
|
||||
return 'W'
|
||||
if '' in self.bd:
|
||||
return 'C'
|
||||
for i in [0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14]:
|
||||
if self.bd[i] == self.bd[i+1]:
|
||||
return 'C'
|
||||
for i in range(12):
|
||||
if self.bd[i] == self.bd[i+4]:
|
||||
return 'C'
|
||||
return 'L'
|
||||
|
||||
# ************************************************
|
||||
|
||||
class Game:
|
||||
def __init__(self, gw):
|
||||
self.window = gw
|
||||
|
||||
self.rosybrown1 = '#ffc1c1'
|
||||
self.lemonchiffon = '#fffacd'
|
||||
self.skyblue1 = '#87ceff'
|
||||
self.springgreen = '#00ff7f'
|
||||
self.tomato1 = '#ff6347'
|
||||
self.hotpink = '#ff69b4'
|
||||
self.brilliantlavender = '#edcaf6'
|
||||
self.cobaltgreen = '#3d9140'
|
||||
self.dodgerblue = '#1e90ff'
|
||||
self.darkgoldenrod1 = '#ffb90f'
|
||||
self.yellow = '#ffff00'
|
||||
self.imperialred = '#ed2939'
|
||||
self.navyblue = '#000080'
|
||||
self.lightgreen = '#90ee90'
|
||||
self.lightsteelblue = '#b0c4de'
|
||||
self.white = '#ffffff'
|
||||
self.palegreen4 = '#548b54'
|
||||
self.darkgreen = '#013220'
|
||||
self.black = '#000000'
|
||||
|
||||
self.doc = {'':self.rosybrown1,
|
||||
'2':self.lemonchiffon,
|
||||
'4':self.skyblue1,
|
||||
'8':self.springgreen,
|
||||
'16':self.tomato1,
|
||||
'32':self.hotpink,
|
||||
'64':self.brilliantlavender,
|
||||
'128':self.cobaltgreen,
|
||||
'256':self.dodgerblue,
|
||||
'512':self.darkgoldenrod1,
|
||||
'1024':self.yellow,
|
||||
'2048':self.imperialred}
|
||||
|
||||
# game data:
|
||||
self.bd = None
|
||||
self.playable = False
|
||||
|
||||
# top frame:
|
||||
self.top_fr = Frame(gw,
|
||||
width=600,
|
||||
height=100,
|
||||
bg=self.lightgreen)
|
||||
self.top_fr.pack(fill=X)
|
||||
|
||||
self.hdg = Label(self.top_fr,
|
||||
text=' 2048 ',
|
||||
font='arial 22 bold',
|
||||
fg=self.navyblue,
|
||||
bg=self.white)
|
||||
self.hdg.place(relx=0.5, rely=0.4,
|
||||
anchor=CENTER)
|
||||
|
||||
self.dir = Label(self.top_fr,
|
||||
text="(Select a 'Goal' & Click 'New Game')",
|
||||
font='arial 12 ',
|
||||
fg=self.navyblue,
|
||||
bg=self.lightgreen)
|
||||
self.dir.place(relx=0.5, rely=0.8,
|
||||
anchor=CENTER)
|
||||
|
||||
self.play_btn = Button(self.top_fr,
|
||||
text='New \nGame',
|
||||
bd=5,
|
||||
bg=self.palegreen4,
|
||||
fg=self.white,
|
||||
font='times 12 bold',
|
||||
command=self.new_game)
|
||||
self.play_btn.place(relx=0.92, rely=0.5,
|
||||
anchor=E)
|
||||
|
||||
self.lbl_cb = Label(self.top_fr,
|
||||
text=' Goal',
|
||||
font='arial 12 bold ',
|
||||
fg=self.darkgreen,
|
||||
bg=self.lightgreen)
|
||||
self.lbl_cb.place(relx=0.08, rely=0.35,
|
||||
anchor=W)
|
||||
|
||||
goals = ['2048', '1024', '512', '256', '128']
|
||||
self.cur_goal = StringVar()
|
||||
self.goal_cb = ttk.Combobox(self.top_fr,
|
||||
foreground=self.darkgreen,
|
||||
values=goals,
|
||||
font='times 12 bold',
|
||||
justify='left',
|
||||
state='readonly',
|
||||
textvariable=self.cur_goal,
|
||||
width=7,
|
||||
height=30)
|
||||
self.goal_cb.place(relx=0.08, rely=0.6,
|
||||
anchor=W)
|
||||
self.goal_cb.current(0)
|
||||
|
||||
# bottom frame:
|
||||
self.btm_fr = Frame(gw,
|
||||
width=600,
|
||||
height=500,
|
||||
bg=self.lightsteelblue)
|
||||
self.btm_fr.pack(fill=X)
|
||||
|
||||
# board frame:
|
||||
self.bd_fr = Frame(self.btm_fr,
|
||||
width=400+2,
|
||||
height=400+2,
|
||||
relief='solid',
|
||||
bd=1,
|
||||
bg=self.lemonchiffon)
|
||||
self.bd_fr.place(relx=0.5, rely=0.5,
|
||||
anchor=CENTER)
|
||||
|
||||
self.bd = Board()
|
||||
self.play_game()
|
||||
|
||||
# ************************************************
|
||||
|
||||
# action to take if 'new game' button is clicked
|
||||
# or if 'play again' is chosen after win or loss:
|
||||
def new_game(self):
|
||||
self.playable = True
|
||||
self.bd = Board()
|
||||
self.bd.place_two()
|
||||
self.bd.goal = self.goal_cb.get()
|
||||
self.goal_cb.config(state='disabled')
|
||||
self.dir.config(text='(Use arrow keys to play game)')
|
||||
self.play_game()
|
||||
|
||||
# show current contents of board:
|
||||
def play_game(self):
|
||||
objh = 100 # widget height
|
||||
objw = 100 # widget width
|
||||
objx = 0 # x-position of widget in frame
|
||||
objy = 0 # y-position of widget in frame
|
||||
|
||||
i = 0
|
||||
for r in range(4):
|
||||
for c in range(4):
|
||||
txt = self.bd.get_text(i)
|
||||
bg_color = self.doc[txt]
|
||||
game_sq = Label(self.bd_fr,
|
||||
text=txt,
|
||||
relief='solid',
|
||||
bd=1,
|
||||
fg=self.black,
|
||||
bg=bg_color,
|
||||
font='times 16 bold')
|
||||
game_sq.place(x=objx, y=objy,
|
||||
height=objh, width=objw)
|
||||
i += 1
|
||||
objx = objx + objw
|
||||
objx = 0
|
||||
objy = objy + objh
|
||||
|
||||
# control play when an arrow key is pressed:
|
||||
def key(self, event):
|
||||
if event.keysym in ('Left', 'Right', 'Up', 'Down'):
|
||||
if self.playable:
|
||||
self.bd.move_squares(event.keysym[0])
|
||||
self.play_game()
|
||||
x = self.bd.is_end()
|
||||
if x == 'C':
|
||||
return
|
||||
elif x == 'W':
|
||||
msg = 'You won!!! Play again?'
|
||||
elif x == 'L':
|
||||
msg = 'You lost!!! Play again?'
|
||||
ans = messagebox.askquestion(msg)
|
||||
if ans == 'no':
|
||||
self.window.destroy()
|
||||
else:
|
||||
self.new_game()
|
||||
|
||||
# ************************************************
|
||||
|
||||
root = Tk()
|
||||
root.title('2048')
|
||||
root.geometry('600x600+100+50')
|
||||
root.resizable(False, False)
|
||||
g = Game(root)
|
||||
root.bind_all('<Key>', g.key)
|
||||
root.mainloop()
|
||||
Loading…
Add table
Add a link
Reference in a new issue