Python
python3

伝説のゲーム「2048」をPythonで自作してAIに解かせる(2) ~Pythonで「2048」を自作する~

伝説のゲーム「2048」をPythonで自作し、自作のAIに解かせます。
これ自体はありふれたテーマで、ググれば色々出てくるのですが、僕みたいな初心者向けに書かれた詳しい記事は見つからなかったので、敢えて書いてみることにしました。

この記事では、Pythonで「2048」を自作します。

なおこの記事は続編です。前の記事は以下のリンクからどうぞ。
https://qiita.com/masa_ramen/items/b497e547a1298a905a2e

AIが「2048」を解いている様子を今すぐご覧になりたい方は、以下の僕のツイートをどうぞ。
https://twitter.com/masa_ramen/status/962957952683450368

環境

  • MacBook Pro (15-inch, 2016)
  • OS: macOS High Sierra (10.13.5)
  • Python 3.6.4
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.13.5
BuildVersion:   17F77
$ python --version
Python 3.6.4 :: Anaconda custom (64-bit)

前記事のおさらい

前回の記事(https://qiita.com/masa_ramen/items/b497e547a1298a905a2e )では、Seleniumというライブラリを使ってWebページ上の「2048」をパソコンにプレイさせました。

Webページ上の「2048」のリンクは以下です[1]。
https://gabrielecirulli.github.io/2048/

for文で
「上」「右」「下」「左」「上」「右」「下」「左」「上」「右」「下」「左」「上」「右」「下」「左」「上」「右」「下」「左」「上」「右」「下」「左」「上」「右」「下」「左」「上」「右」「下」「左」「上」「右」「下」「左」「上」「右」「下」「左」・・・「上」「右」「下」「左」
のような指示を送信することで、パソコンがそこそこの得点をゲットする様子を見ました。
ところが知性皆無のキチガイな戦略では限界があるため、
盤面を認識して、
ある方向を送信した時の結果(=「1手先」の盤面)を計算して、
それがどれくらい「良い」かを評価し、一番「良い手」を選び続ける
プログラム

の作成が必要であるとの結論に至りました。

「2048」の自作が必要

盤面の認識については、前回も使ったSeleniumライブラリで対応できます。
しかし、認識した盤面において「1手先」を計算するためには「自分の頭の中」に「2048」が必要です。
パソコンが自分で「2048」のルールを理解し、そのルールに則って次の局面を計算する必要があるのです。
では、「2048」のルールを確認しましょう。

「2048」のルール

①はじめに4×4の空席がある
②このうちランダムな2ヶ所にタイルが出現する
③方向キーの入力を受け付ける(今回のプログラムでは、上を「u」、右を「r」、下を「d」、左を「l」としました)
④数字がくっついたら、くっついた後の数字を得点に加算する
⑤ランダムな場所に新しいタイルが出現する
(以下、③〜⑤を繰り返す)

新しく出現するタイルは、90%で「2」が出現し、10%で「4」が出現するとします。

コード

あとはルールをPython語に翻訳するだけです。
愚直に書いたため、長くて読みにくいですごめんなさい🙏
皆さんも実際に遊んで見てください。
上に動かしたいときは「u」、右に動かしたいときは「r」、下に動かしたいときは「d」、左に動かしたいときは「l」と入力してください。

次回の記事では、いよいよ評価関数を導入して、それぞれの「次の1手」がどれくらい「良い」かを点数で表示する機能を実装します!お楽しみに!

self2048.py
# ライブラリのインポート
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import shutil
import numpy as np
import pprint
import time
import copy
from numpy.random import *
import math

# デバッグ
import logging
logging.basicConfig(level=logging.DEBUG, format=' %(asctime)s - %(levelname)s - %(message)s')
logging.debug('Start of program')
logging.disable(logging.CRITICAL)# debugしない

def print_board(board):# 盤を見やすく表示
    print('  ' + '____'*4)
    print(' | ' + board['1-1'] + ' | ' + board['2-1'] + ' | ' + board['3-1'] + ' | ' + board['4-1'] + ' | ')
    print(' | ' + board['1-2'] + ' | ' + board['2-2'] + ' | ' + board['3-2'] + ' | ' + board['4-2'] + ' | ')
    print(' | ' + board['1-3'] + ' | ' + board['2-3'] + ' | ' + board['3-3'] + ' | ' + board['4-3'] + ' | ')
    print(' | ' + board['1-4'] + ' | ' + board['2-4'] + ' | ' + board['3-4'] + ' | ' + board['4-4'] + ' | ')
    print('  ' + '____'*4)

def move_tile(next_board,a,b):
    next_board[b] = next_board[a]
    next_board[a] = '0'
    return next_board# タイルの移動

def sum_tile(next_board,c,d,end):
    c_num = int(next_board[c])
    d_num = int(next_board[d])
    next_board[c] = '0'
    next_board[d] = str(c_num + d_num)
    if end==0:
        global score
        print('{0}+{1}={2}'.format(c_num,d_num,c_num+d_num))
        score += c_num + d_num
    return next_board# タイルの結合

def down_move(next_board,end):# 下方向移動
    if next_board['1-4']=='0':# ok
        if next_board['1-3']=='0':# ok
            if next_board['1-2']=='0':# ok
                if next_board['1-1']=='0':
                    #[0,0,0,0]->何もしない
                    logging.debug('hoge')
                elif next_board['1-1']!='0':
                    #[2,0,0,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'1-1','1-4')
            elif next_board['1-2']!='0':# ok
                if next_board['1-1']=='0':
                    #[0,2,0,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'1-2','1-4')
                elif next_board['1-1']!='0':
                    if next_board['1-1']==next_board['1-2']:
                        #[2,2,0,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'1-1','1-2',end)
                        next_board = move_tile(next_board,'1-2','1-4')
                    elif next_board['1-1']!=next_board['1-2']:
                        #[2,4,0,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'1-2','1-4')
                        next_board = move_tile(next_board,'1-1','1-3')
        elif next_board['1-3']!='0':# ok
            if next_board['1-2']=='0':# ok
                if next_board['1-1']=='0':# ok
                    #[0,0,2,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'1-3','1-4')
                elif next_board['1-1']!='0':# ok
                    if next_board['1-1']==next_board['1-3']:# ok
                        #[2,0,2,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'1-1','1-3',end)
                        next_board = move_tile(next_board,'1-3','1-4')
                    elif next_board['1-1']!=next_board['1-3']:# ok
                        #[2,0,4,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'1-3','1-4')
                        next_board = move_tile(next_board,'1-1','1-3')
            elif next_board['1-2']!='0':# ok
                if next_board['1-1']=='0':# ok
                    if next_board['1-2']==next_board['1-3']:# ok
                        #[0,2,2,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'1-2','1-3',end)
                        next_board = move_tile(next_board,'1-3','1-4')
                    elif next_board['1-2']!=next_board['1-3']:# ok
                        #[0,2,4,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'1-3','1-4')
                        next_board = move_tile(next_board,'1-2','1-3')
                elif next_board['1-1']!='0':# ok
                    if next_board['1-2']==next_board['1-3']:# ok
                        #[2,2,2,0]->[0,0,2,4]
                        next_board = sum_tile(next_board,'1-2','1-3',end)
                        next_board = move_tile(next_board,'1-3','1-4')
                        next_board = move_tile(next_board,'1-1','1-3')
                    elif next_board['1-1']==next_board['1-2']:# ok
                        #[2,2,4,0]->[0,0,4,4]
                        next_board = sum_tile(next_board,'1-1','1-2',end)
                        next_board = move_tile(next_board,'1-3','1-4')
                        next_board = move_tile(next_board,'1-2','1-3')
                    else:# ok
                        #[2,4,8,0]->[0,2,4,8]
                        next_board = move_tile(next_board,'1-3','1-4')
                        next_board = move_tile(next_board,'1-2','1-3')
                        next_board = move_tile(next_board,'1-1','1-2')
    elif next_board['1-4']!='0':# ok
        if next_board['1-3']=='0':# ok
            if next_board['1-2']=='0':# ok
                if next_board['1-1']=='0':# ok
                    #[0,0,0,2]->何もしない
                    logging.debug('hoge')
                elif next_board['1-1']!='0':# ok
                    if next_board['1-1']==next_board['1-4']:# ok
                        #[2,0,0,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'1-1','1-4',end)
                    elif next_board['1-1']!=next_board['1-4']:# ok
                        #[2,0,0,4]->[0,0,2,4]
                        next_board = move_tile(next_board,'1-1','1-3')
            elif next_board['1-2']!='0':# ok
                if next_board['1-1']=='0':# ok
                    if next_board['1-2']==next_board['1-4']:# ok
                        #[0,2,0,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'1-2','1-4',end)
                    elif next_board['1-2']!=next_board['1-4']:# ok
                        #[0,2,0,4]->[0,0,2,4]
                        next_board = move_tile(next_board,'1-2','1-3')
                elif next_board['1-1']!='0':# ok
                    if next_board['1-1']==next_board['1-2']:# ok #ミス
                        #[2,2,0,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'1-1','1-2',end)
                        next_board = move_tile(next_board,'1-2','1-3')
                    elif next_board['1-1']!=next_board['1-2']:# ok
                        #[2,4,0,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'1-2','1-4')
                        next_board = move_tile(next_board,'1-1','1-3')
        elif next_board['1-3']!='0':# ok
            if next_board['1-2']=='0':# ok
                if next_board['1-1']=='0':# ok
                    if next_board['1-3']==next_board['1-4']:# ok
                        #[0,0,2,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'1-3','1-4',end)
                    elif next_board['1-3']!=next_board['1-4']:# ok
                        #[0,0,2,4]->[0,0,2,4]
                        logging.debug('hoge')
                elif next_board['1-1']!='0':# ok
                    if next_board['1-3']==next_board['1-4']:# ok
                        #[2,0,2,2]->[0,0,2,4]
                        next_board = sum_tile(next_board,'1-3','1-4',end)
                        next_board = move_tile(next_board,'1-1','1-3')
                    elif next_board['1-1']==next_board['1-3']:# ok
                        #[2,0,2,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'1-1','1-3',end)
                    else:# ok
                        #[2,0,4,8]->[0,2,4,8]
                        next_board = move_tile(next_board,'1-1','1-2')
            elif next_board['1-2']!='0':# ok
                if next_board['1-1']=='0':# ok
                    if next_board['1-3']==next_board['1-4']:# ok
                        #[0,2,2,2]->[0,0,2,4]
                        next_board = sum_tile(next_board,'1-3','1-4',end)
                        next_board = move_tile(next_board,'1-2','1-3')
                    elif next_board['1-2']==next_board['1-3']:# ok
                        #[0,2,2,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'1-2','1-3',end)
                    else:# ok
                        #[0,2,4,8]->[0,2,4,8]
                        logging.debug('hoge')
                elif next_board['1-1']!='0':#全部違う場合->ok
                    if next_board['1-3']==next_board['1-4']:# ok
                        if next_board['1-1']==next_board['1-2']:# ok
                            #[2,2,2,2]->[0,0,4,4]
                            next_board = sum_tile(next_board,'1-3','1-4',end)
                            next_board = sum_tile(next_board,'1-1','1-2',end)
                            next_board = move_tile(next_board,'1-2','1-3')
                        else:# ok
                            #[2,4,2,2]->[0,2,4,4]
                            next_board = sum_tile(next_board,'1-3','1-4',end)
                            next_board = move_tile(next_board,'1-2','1-3')
                            next_board = move_tile(next_board,'1-1','1-2')
                    elif next_board['1-2']==next_board['1-3'] and next_board['1-3']!=next_board['1-4']:# ok
                        #[2,2,2,4]->[0,2,4,4]
                        next_board = sum_tile(next_board,'1-2','1-3',end)
                        next_board = move_tile(next_board,'1-1','1-2')
                    elif next_board['1-1']==next_board['1-2'] and next_board['1-2']!=next_board['1-3'] and next_board['1-3']!=next_board['1-4']:# ok
                        #[2,2,4,8]->[0,4,4,8]
                        next_board = sum_tile(next_board,'1-1','1-2',end)
                    else:# ok
                        #[2,4,8,16]->[2,4,8,16]
                        logging.debug('hoge')

    if next_board['2-4']=='0':# ok
        if next_board['2-3']=='0':# ok
            if next_board['2-2']=='0':# ok
                if next_board['2-1']=='0':
                    #[0,0,0,0]->何もしない
                    logging.debug('hoge')
                elif next_board['2-1']!='0':
                    #[2,0,0,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'2-1','2-4')
            elif next_board['2-2']!='0':# ok
                if next_board['2-1']=='0':
                    #[0,2,0,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'2-2','2-4')
                elif next_board['2-1']!='0':
                    if next_board['2-1']==next_board['2-2']:
                        #[2,2,0,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'2-1','2-2',end)
                        next_board = move_tile(next_board,'2-2','2-4')
                    elif next_board['2-1']!=next_board['2-2']:
                        #[2,4,0,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'2-2','2-4')
                        next_board = move_tile(next_board,'2-1','2-3')
        elif next_board['2-3']!='0':# ok
            if next_board['2-2']=='0':# ok
                if next_board['2-1']=='0':# ok
                    #[0,0,2,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'2-3','2-4')
                elif next_board['2-1']!='0':# ok
                    if next_board['2-1']==next_board['2-3']:# ok
                        #[2,0,2,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'2-1','2-3',end)
                        next_board = move_tile(next_board,'2-3','2-4')
                    elif next_board['2-1']!=next_board['2-3']:# ok
                        #[2,0,4,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'2-3','2-4')
                        next_board = move_tile(next_board,'2-1','2-3')
            elif next_board['2-2']!='0':# ok
                if next_board['2-1']=='0':# ok
                    if next_board['2-2']==next_board['2-3']:# ok
                        #[0,2,2,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'2-2','2-3',end)
                        next_board = move_tile(next_board,'2-3','2-4')
                    elif next_board['2-2']!=next_board['2-3']:# ok
                        #[0,2,4,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'2-3','2-4')
                        next_board = move_tile(next_board,'2-2','2-3')
                elif next_board['2-1']!='0':# ok
                    if next_board['2-2']==next_board['2-3']:# ok
                        #[2,2,2,0]->[0,0,2,4]
                        next_board = sum_tile(next_board,'2-2','2-3',end)
                        next_board = move_tile(next_board,'2-3','2-4')
                        next_board = move_tile(next_board,'2-1','2-3')
                    elif next_board['2-1']==next_board['2-2']:# ok
                        #[2,2,4,0]->[0,0,4,4]
                        next_board = sum_tile(next_board,'2-1','2-2',end)
                        next_board = move_tile(next_board,'2-3','2-4')
                        next_board = move_tile(next_board,'2-2','2-3')
                    else:# ok
                        #[2,4,8,0]->[0,2,4,8]
                        next_board = move_tile(next_board,'2-3','2-4')
                        next_board = move_tile(next_board,'2-2','2-3')
                        next_board = move_tile(next_board,'2-1','2-2')
    elif next_board['2-4']!='0':# ok
        if next_board['2-3']=='0':# ok
            if next_board['2-2']=='0':# ok
                if next_board['2-1']=='0':# ok
                    #[0,0,0,2]->何もしない
                    logging.debug('hoge')
                elif next_board['2-1']!='0':# ok
                    if next_board['2-1']==next_board['2-4']:# ok
                        #[2,0,0,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'2-1','2-4',end)
                    elif next_board['2-1']!=next_board['2-4']:# ok
                        #[2,0,0,4]->[0,0,2,4]
                        next_board = move_tile(next_board,'2-1','2-3')
            elif next_board['2-2']!='0':# ok
                if next_board['2-1']=='0':# ok
                    if next_board['2-2']==next_board['2-4']:# ok
                        #[0,2,0,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'2-2','2-4',end)
                    elif next_board['2-2']!=next_board['2-4']:# ok
                        #[0,2,0,4]->[0,0,2,4]
                        next_board = move_tile(next_board,'2-2','2-3')
                elif next_board['2-1']!='0':# ok
                    if next_board['2-1']==next_board['2-2']:# ok #ミス
                        #[2,2,0,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'2-1','2-2',end)
                        next_board = move_tile(next_board,'2-2','2-3')
                    elif next_board['2-1']!=next_board['2-2']:# ok
                        #[2,4,0,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'2-2','2-4')
                        next_board = move_tile(next_board,'2-1','2-3')
        elif next_board['2-3']!='0':# ok
            if next_board['2-2']=='0':# ok
                if next_board['2-1']=='0':# ok
                    if next_board['2-3']==next_board['2-4']:# ok
                        #[0,0,2,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'2-3','2-4',end)
                    elif next_board['2-3']!=next_board['2-4']:# ok
                        #[0,0,2,4]->[0,0,2,4]
                        logging.debug('hoge')
                elif next_board['2-1']!='0':# ok
                    if next_board['2-3']==next_board['2-4']:# ok
                        #[2,0,2,2]->[0,0,2,4]
                        next_board = sum_tile(next_board,'2-3','2-4',end)
                        next_board = move_tile(next_board,'2-1','2-3')
                    elif next_board['2-1']==next_board['2-3']:# ok
                        #[2,0,2,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'2-1','2-3',end)
                    else:# ok
                        #[2,0,4,8]->[0,2,4,8]
                        next_board = move_tile(next_board,'2-1','2-2')
            elif next_board['2-2']!='0':# ok
                if next_board['2-1']=='0':# ok
                    if next_board['2-3']==next_board['2-4']:# ok
                        #[0,2,2,2]->[0,0,2,4]
                        next_board = sum_tile(next_board,'2-3','2-4',end)
                        next_board = move_tile(next_board,'2-2','2-3')
                    elif next_board['2-2']==next_board['2-3']:# ok
                        #[0,2,2,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'2-2','2-3',end)
                    else:# ok
                        #[0,2,4,8]->[0,2,4,8]
                        logging.debug('hoge')
                elif next_board['2-1']!='0':#全部違う場合->ok
                    if next_board['2-3']==next_board['2-4']:# ok
                        if next_board['2-1']==next_board['2-2']:# ok
                            #[2,2,2,2]->[0,0,4,4]
                            next_board = sum_tile(next_board,'2-3','2-4',end)
                            next_board = sum_tile(next_board,'2-1','2-2',end)
                            next_board = move_tile(next_board,'2-2','2-3')
                        else:# ok
                            #[2,4,2,2]->[0,2,4,4]
                            next_board = sum_tile(next_board,'2-3','2-4',end)
                            next_board = move_tile(next_board,'2-2','2-3')
                            next_board = move_tile(next_board,'2-1','2-2')
                    elif next_board['2-2']==next_board['2-3'] and next_board['2-3']!=next_board['2-4']:# ok
                        #[2,2,2,4]->[0,2,4,4]
                        next_board = sum_tile(next_board,'2-2','2-3',end)
                        next_board = move_tile(next_board,'2-1','2-2')
                    elif next_board['2-1']==next_board['2-2'] and next_board['2-2']!=next_board['2-3'] and next_board['2-3']!=next_board['2-4']:# ok
                        #[2,2,4,8]->[0,4,4,8]
                        next_board = sum_tile(next_board,'2-1','2-2',end)
                    else:# ok
                        #[2,4,8,16]->[2,4,8,16]
                        logging.debug('hoge')

    if next_board['3-4']=='0':# ok
        if next_board['3-3']=='0':# ok
            if next_board['3-2']=='0':# ok
                if next_board['3-1']=='0':
                    #[0,0,0,0]->何もしない
                    logging.debug('hoge')
                elif next_board['3-1']!='0':
                    #[2,0,0,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'3-1','3-4')
            elif next_board['3-2']!='0':# ok
                if next_board['3-1']=='0':
                    #[0,2,0,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'3-2','3-4')
                elif next_board['3-1']!='0':
                    if next_board['3-1']==next_board['3-2']:
                        #[2,2,0,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'3-1','3-2',end)
                        next_board = move_tile(next_board,'3-2','3-4')
                    elif next_board['3-1']!=next_board['3-2']:
                        #[2,4,0,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'3-2','3-4')
                        next_board = move_tile(next_board,'3-1','3-3')
        elif next_board['3-3']!='0':# ok
            if next_board['3-2']=='0':# ok
                if next_board['3-1']=='0':# ok
                    #[0,0,2,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'3-3','3-4')
                elif next_board['3-1']!='0':# ok
                    if next_board['3-1']==next_board['3-3']:# ok
                        #[2,0,2,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'3-1','3-3',end)
                        next_board = move_tile(next_board,'3-3','3-4')
                    elif next_board['3-1']!=next_board['3-3']:# ok
                        #[2,0,4,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'3-3','3-4')
                        next_board = move_tile(next_board,'3-1','3-3')
            elif next_board['3-2']!='0':# ok
                if next_board['3-1']=='0':# ok
                    if next_board['3-2']==next_board['3-3']:# ok
                        #[0,2,2,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'3-2','3-3',end)
                        next_board = move_tile(next_board,'3-3','3-4')
                    elif next_board['3-2']!=next_board['3-3']:# ok
                        #[0,2,4,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'3-3','3-4')
                        next_board = move_tile(next_board,'3-2','3-3')
                elif next_board['3-1']!='0':# ok
                    if next_board['3-2']==next_board['3-3']:# ok
                        #[2,2,2,0]->[0,0,2,4]
                        next_board = sum_tile(next_board,'3-2','3-3',end)
                        next_board = move_tile(next_board,'3-3','3-4')
                        next_board = move_tile(next_board,'3-1','3-3')
                    elif next_board['3-1']==next_board['3-2']:# ok
                        #[2,2,4,0]->[0,0,4,4]
                        next_board = sum_tile(next_board,'3-1','3-2',end)
                        next_board = move_tile(next_board,'3-3','3-4')
                        next_board = move_tile(next_board,'3-2','3-3')
                    else:# ok
                        #[2,4,8,0]->[0,2,4,8]
                        next_board = move_tile(next_board,'3-3','3-4')
                        next_board = move_tile(next_board,'3-2','3-3')
                        next_board = move_tile(next_board,'3-1','3-2')
    elif next_board['3-4']!='0':# ok
        if next_board['3-3']=='0':# ok
            if next_board['3-2']=='0':# ok
                if next_board['3-1']=='0':# ok
                    #[0,0,0,2]->何もしない
                    logging.debug('hoge')
                elif next_board['3-1']!='0':# ok
                    if next_board['3-1']==next_board['3-4']:# ok
                        #[2,0,0,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'3-1','3-4',end)
                    elif next_board['3-1']!=next_board['3-4']:# ok
                        #[2,0,0,4]->[0,0,2,4]
                        next_board = move_tile(next_board,'3-1','3-3')
            elif next_board['3-2']!='0':# ok
                if next_board['3-1']=='0':# ok
                    if next_board['3-2']==next_board['3-4']:# ok
                        #[0,2,0,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'3-2','3-4',end)
                    elif next_board['3-2']!=next_board['3-4']:# ok
                        #[0,2,0,4]->[0,0,2,4]
                        next_board = move_tile(next_board,'3-2','3-3')
                elif next_board['3-1']!='0':# ok
                    if next_board['3-1']==next_board['3-2']:# ok #ミス
                        #[2,2,0,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'3-1','3-2',end)
                        next_board = move_tile(next_board,'3-2','3-3')
                    elif next_board['3-1']!=next_board['3-2']:# ok
                        #[2,4,0,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'3-2','3-4')
                        next_board = move_tile(next_board,'3-1','3-3')
        elif next_board['3-3']!='0':# ok
            if next_board['3-2']=='0':# ok
                if next_board['3-1']=='0':# ok
                    if next_board['3-3']==next_board['3-4']:# ok
                        #[0,0,2,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'3-3','3-4',end)
                    elif next_board['3-3']!=next_board['3-4']:# ok
                        #[0,0,2,4]->[0,0,2,4]
                        logging.debug('hoge')
                elif next_board['3-1']!='0':# ok
                    if next_board['3-3']==next_board['3-4']:# ok
                        #[2,0,2,2]->[0,0,2,4]
                        next_board = sum_tile(next_board,'3-3','3-4',end)
                        next_board = move_tile(next_board,'3-1','3-3')
                    elif next_board['3-1']==next_board['3-3']:# ok
                        #[2,0,2,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'3-1','3-3',end)
                    else:# ok
                        #[2,0,4,8]->[0,2,4,8]
                        next_board = move_tile(next_board,'3-1','3-2')
            elif next_board['3-2']!='0':# ok
                if next_board['3-1']=='0':# ok
                    if next_board['3-3']==next_board['3-4']:# ok
                        #[0,2,2,2]->[0,0,2,4]
                        next_board = sum_tile(next_board,'3-3','3-4',end)
                        next_board = move_tile(next_board,'3-2','3-3')
                    elif next_board['3-2']==next_board['3-3']:# ok
                        #[0,2,2,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'3-2','3-3',end)
                    else:# ok
                        #[0,2,4,8]->[0,2,4,8]
                        logging.debug('hoge')
                elif next_board['3-1']!='0':#全部違う場合->ok
                    if next_board['3-3']==next_board['3-4']:# ok
                        if next_board['3-1']==next_board['3-2']:# ok
                            #[2,2,2,2]->[0,0,4,4]
                            next_board = sum_tile(next_board,'3-3','3-4',end)
                            next_board = sum_tile(next_board,'3-1','3-2',end)
                            next_board = move_tile(next_board,'3-2','3-3')
                        else:# ok
                            #[2,4,2,2]->[0,2,4,4]
                            next_board = sum_tile(next_board,'3-3','3-4',end)
                            next_board = move_tile(next_board,'3-2','3-3')
                            next_board = move_tile(next_board,'3-1','3-2')
                    elif next_board['3-2']==next_board['3-3'] and next_board['3-3']!=next_board['3-4']:# ok
                        #[2,2,2,4]->[0,2,4,4]
                        next_board = sum_tile(next_board,'3-2','3-3',end)
                        next_board = move_tile(next_board,'3-1','3-2')
                    elif next_board['3-1']==next_board['3-2'] and next_board['3-2']!=next_board['3-3'] and next_board['3-3']!=next_board['3-4']:# ok
                        #[2,2,4,8]->[0,4,4,8]
                        next_board = sum_tile(next_board,'3-1','3-2',end)
                    else:# ok
                        #[2,4,8,16]->[2,4,8,16]
                        logging.debug('hoge')

    if next_board['4-4']=='0':# ok
        if next_board['4-3']=='0':# ok
            if next_board['4-2']=='0':# ok
                if next_board['4-1']=='0':
                    #[0,0,0,0]->何もしない
                    logging.debug('hoge')
                elif next_board['4-1']!='0':
                    #[2,0,0,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'4-1','4-4')
            elif next_board['4-2']!='0':# ok
                if next_board['4-1']=='0':
                    #[0,2,0,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'4-2','4-4')
                elif next_board['4-1']!='0':
                    if next_board['4-1']==next_board['4-2']:
                        #[2,2,0,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'4-1','4-2',end)
                        next_board = move_tile(next_board,'4-2','4-4')
                    elif next_board['4-1']!=next_board['4-2']:
                        #[2,4,0,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'4-2','4-4')
                        next_board = move_tile(next_board,'4-1','4-3')
        elif next_board['4-3']!='0':# ok
            if next_board['4-2']=='0':# ok
                if next_board['4-1']=='0':# ok
                    #[0,0,2,0]->[0,0,0,2]
                    next_board = move_tile(next_board,'4-3','4-4')
                elif next_board['4-1']!='0':# ok
                    if next_board['4-1']==next_board['4-3']:# ok
                        #[2,0,2,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'4-1','4-3',end)
                        next_board = move_tile(next_board,'4-3','4-4')
                    elif next_board['4-1']!=next_board['4-3']:# ok
                        #[2,0,4,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'4-3','4-4')
                        next_board = move_tile(next_board,'4-1','4-3')
            elif next_board['4-2']!='0':# ok
                if next_board['4-1']=='0':# ok
                    if next_board['4-2']==next_board['4-3']:# ok
                        #[0,2,2,0]->[0,0,0,4]
                        next_board = sum_tile(next_board,'4-2','4-3',end)
                        next_board = move_tile(next_board,'4-3','4-4')
                    elif next_board['4-2']!=next_board['4-3']:# ok
                        #[0,2,4,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'4-3','4-4')
                        next_board = move_tile(next_board,'4-2','4-3')
                elif next_board['4-1']!='0':# ok
                    if next_board['4-2']==next_board['4-3']:# ok
                        #[2,2,2,0]->[0,0,2,4]
                        next_board = sum_tile(next_board,'4-2','4-3',end)
                        next_board = move_tile(next_board,'4-3','4-4')
                        next_board = move_tile(next_board,'4-1','4-3')
                    elif next_board['4-1']==next_board['4-2']:# ok
                        #[2,2,4,0]->[0,0,4,4]
                        next_board = sum_tile(next_board,'4-1','4-2',end)
                        next_board = move_tile(next_board,'4-3','4-4')
                        next_board = move_tile(next_board,'4-2','4-3')
                    else:# ok
                        #[2,4,8,0]->[0,2,4,8]
                        next_board = move_tile(next_board,'4-3','4-4')
                        next_board = move_tile(next_board,'4-2','4-3')
                        next_board = move_tile(next_board,'4-1','4-2')
    elif next_board['4-4']!='0':# ok
        if next_board['4-3']=='0':# ok
            if next_board['4-2']=='0':# ok
                if next_board['4-1']=='0':# ok
                    #[0,0,0,2]->何もしない
                    logging.debug('hoge')
                elif next_board['4-1']!='0':# ok
                    if next_board['4-1']==next_board['4-4']:# ok
                        #[2,0,0,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'4-1','4-4',end)
                    elif next_board['4-1']!=next_board['4-4']:# ok
                        #[2,0,0,4]->[0,0,2,4]
                        next_board = move_tile(next_board,'4-1','4-3')
            elif next_board['4-2']!='0':# ok
                if next_board['4-1']=='0':# ok
                    if next_board['4-2']==next_board['4-4']:# ok
                        #[0,2,0,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'4-2','4-4',end)
                    elif next_board['4-2']!=next_board['4-4']:# ok
                        #[0,2,0,4]->[0,0,2,4]
                        next_board = move_tile(next_board,'4-2','4-3')
                elif next_board['4-1']!='0':# ok
                    if next_board['4-1']==next_board['4-2']:# ok #ミス
                        #[2,2,0,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'4-1','4-2',end)
                        next_board = move_tile(next_board,'4-2','4-3')
                    elif next_board['4-1']!=next_board['4-2']:# ok
                        #[2,4,0,0]->[0,0,2,4]
                        next_board = move_tile(next_board,'4-2','4-4')
                        next_board = move_tile(next_board,'4-1','4-3')
        elif next_board['4-3']!='0':# ok
            if next_board['4-2']=='0':# ok
                if next_board['4-1']=='0':# ok
                    if next_board['4-3']==next_board['4-4']:# ok
                        #[0,0,2,2]->[0,0,0,4]
                        next_board = sum_tile(next_board,'4-3','4-4',end)
                    elif next_board['4-3']!=next_board['4-4']:# ok
                        #[0,0,2,4]->[0,0,2,4]
                        logging.debug('hoge')
                elif next_board['4-1']!='0':# ok
                    if next_board['4-3']==next_board['4-4']:# ok
                        #[2,0,2,2]->[0,0,2,4]
                        next_board = sum_tile(next_board,'4-3','4-4',end)
                        next_board = move_tile(next_board,'4-1','4-3')
                    elif next_board['4-1']==next_board['4-3']:# ok
                        #[2,0,2,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'4-1','4-3',end)
                    else:# ok
                        #[2,0,4,8]->[0,2,4,8]
                        next_board = move_tile(next_board,'4-1','4-2')
            elif next_board['4-2']!='0':# ok
                if next_board['4-1']=='0':# ok
                    if next_board['4-3']==next_board['4-4']:# ok
                        #[0,2,2,2]->[0,0,2,4]
                        next_board = sum_tile(next_board,'4-3','4-4',end)
                        next_board = move_tile(next_board,'4-2','4-3')
                    elif next_board['4-2']==next_board['4-3']:# ok
                        #[0,2,2,4]->[0,0,4,4]
                        next_board = sum_tile(next_board,'4-2','4-3',end)
                    else:# ok
                        #[0,2,4,8]->[0,2,4,8]
                        logging.debug('hoge')
                elif next_board['4-1']!='0':#全部違う場合->ok
                    if next_board['4-3']==next_board['4-4']:# ok
                        if next_board['4-1']==next_board['4-2']:# ok
                            #[2,2,2,2]->[0,0,4,4]
                            next_board = sum_tile(next_board,'4-3','4-4',end)
                            next_board = sum_tile(next_board,'4-1','4-2',end)
                            next_board = move_tile(next_board,'4-2','4-3')
                        else:# ok
                            #[2,4,2,2]->[0,2,4,4]
                            next_board = sum_tile(next_board,'4-3','4-4',end)
                            next_board = move_tile(next_board,'4-2','4-3')
                            next_board = move_tile(next_board,'4-1','4-2')
                    elif next_board['4-2']==next_board['4-3'] and next_board['4-3']!=next_board['4-4']:# ok
                        #[2,2,2,4]->[0,2,4,4]
                        next_board = sum_tile(next_board,'4-2','4-3',end)
                        next_board = move_tile(next_board,'4-1','4-2')
                    elif next_board['4-1']==next_board['4-2'] and next_board['4-2']!=next_board['4-3'] and next_board['4-3']!=next_board['4-4']:# ok
                        #[2,2,4,8]->[0,4,4,8]
                        next_board = sum_tile(next_board,'4-1','4-2',end)
                    else:# ok
                        #[2,4,8,16]->[2,4,8,16]
                        logging.debug('hoge')

    return next_board

def rotate_right(next_board):# 右90度回転
    copy_board = copy.deepcopy(next_board)
    next_board['1-1'] = copy_board['1-4']
    next_board['1-2'] = copy_board['2-4']
    next_board['1-3'] = copy_board['3-4']
    next_board['1-4'] = copy_board['4-4']
    next_board['2-1'] = copy_board['1-3']
    next_board['2-2'] = copy_board['2-3']
    next_board['2-3'] = copy_board['3-3']
    next_board['2-4'] = copy_board['4-3']
    next_board['3-1'] = copy_board['1-2']
    next_board['3-2'] = copy_board['2-2']
    next_board['3-3'] = copy_board['3-2']
    next_board['3-4'] = copy_board['4-2']
    next_board['4-1'] = copy_board['1-1']
    next_board['4-2'] = copy_board['2-1']
    next_board['4-3'] = copy_board['3-1']
    next_board['4-4'] = copy_board['4-1']
    return next_board

def rotate_left(next_board):# 左90度回転
    next_board = rotate_right(next_board)
    next_board = rotate_right(next_board)
    next_board = rotate_right(next_board)
    return next_board

def flick_board(board,direction,end):# direction方向のフリックの結果を返す
    next_board = copy.deepcopy(board)

    if direction=='right':
        next_board = rotate_right(next_board)
        next_board = down_move(next_board,end)
        next_board = rotate_left(next_board)
    elif direction=='down':
        next_board = down_move(next_board,end)
    elif direction=='left':
        next_board = rotate_left(next_board)
        next_board = down_move(next_board,end)
        next_board = rotate_right(next_board)
    elif direction=='up':
        next_board = rotate_right(next_board)
        next_board = rotate_right(next_board)
        next_board = down_move(next_board,end)
        next_board = rotate_left(next_board)
        next_board = rotate_left(next_board)
    else:
        logging.debug('direction error')

    return next_board

def new_tile_appear(board):
    zero_list = []
    for key,value in board.items():
        if value=='0':
            zero_list.append(key)
    random_num = randint(len(zero_list))
    key_selected = zero_list[random_num]

    two_or_four = randint(0,10)
    if two_or_four==9:
        board[key_selected] = '4'
    else:
        board[key_selected] = '2'
    return board

def end_check(board):
    end_cnt = 0
    dirs = ['right','down','left','up']
    for direction in dirs:
        new_board = flick_board(board,direction,1)
        if board == new_board:
            end_cnt += 1
    if end_cnt==4:
        end_flag = 0#どの方向に動かしても局面が変わらない=詰み
    else:
        end_flag = 1
    return end_flag

# ゲーム開始の準備
score = 0# スコアの推移を記録する変数
board = {'1-1':'0','1-2':'0','1-3':'0','1-4':'0',\
'2-1':'0','2-2':'0','2-3':'0','2-4':'0',\
'3-1':'0','3-2':'0','3-3':'0','3-4':'0',\
'4-1':'0','4-2':'0','4-3':'0','4-4':'0'}# 初期設定は全て0

# はじめに二つのタイルを出現させる
board = new_tile_appear(board)
board = new_tile_appear(board)
print_board(board)

cnt = 0
end_flag = 1
while(end_flag):
    cnt += 1
    flag = 0
    while flag==0:
        end_flag = end_check(board)
        if end_flag==0:
            break
        move = input('input {}th move>>> '.format(cnt))
        if move=='r':
            new_board = flick_board(board,'right',0)
        elif move=='d':
            new_board = flick_board(board,'down',0)
        elif move=='l':
            new_board = flick_board(board,'left',0)
        elif move=='u':
            new_board = flick_board(board,'up',0)
        else:
            print('err')

        if board == new_board:
            flag = 0
        elif board != new_board:
            flag = 1
    try:
        new_board = new_tile_appear(new_board)
    except ValueError:
        break
    print_board(new_board)
    board = new_board
    print('score = {}'.format(score))

print('#######################')
print('Game Over')
print('Final Score = {}'.format(score))
print('#######################')

logging.debug('End of program')

参考文献

[1] 2048 (2048が実際に遊べます。iPhone6とMacBook Proで動作確認しました。2018/8/9にアクセスを確認しました。)
https://gabrielecirulli.github.io/2048/