欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Python实现2048小游戏

程序员文章站 2024-03-19 08:59:52
...

2048小游戏

还在测试,有时间在写文案(已更新两次,最新代码在最后面)

import numpy as np
import random
import os

def print_a(a):
    print(" _______________________")
    x = 0
    while x < 4:
        y = 0
        print("|     |     |     |     |")
        while y < 4:
            if a[x][y] == 0:
                print("|    ",end=" ")
            else:
                print("|%4d"%a[x][y],end=" ")
            y += 1
        print("|\n|_____|_____|_____|_____|")
        x += 1
def new_a():
    a = np.zeros([4,4], dtype = int)
    a[xy()] = 2
    a[xy()] = 2
    return a
def xy():
    x = random.randint(0,3)
    y = random.randint(0,3)
    return x,y
def add(a):
    m = random.randint(0,9)
    while True:
        x,y =xy()
        if a[x,y] == 0:
            if m == 0:
                a[x,y] = 4
            else:
                a[x,y] = 2
            break
    return a
def up(a):
    x = 1
    while x < 4:
        y = 0
        while y < 4:
            x1 = x
            while a[x1-1,y] == 0 and a[x1,y] != 0 and x1 > 0:
                a[x1-1,y] = a[x1,y]
                a[x1,y] = 0
                x1 -= 1
            # a列表参数可以为负,所以不用管
            if x1 == 0:
                x1 = 1            
            if a[x1-1,y] == a[x1,y] and a[x1,y] != 0:
                a[x1-1,y] *= 2
                a[x1,y] = 0
            y += 1
        x += 1
    i = check_up(a) 
    if i == 0:
        a = add(a)
        i = check_up(a)
    return a,i
def check_up(a):
    i = 1
    x = 1
    while x < 4:
        y = 0
        while y < 4:
            if a[x,y] == 0 or a[x-1,y] == a[x,y]:
                i = 0
                break
            y += 1
        if i == 0:
            break
        x += 1
    return i
def down(a):
    x = 2
    while x >= 0:
        y = 0
        while y < 4:
            x1 = x
            while x1 < 3 and a[x1+1,y] == 0 and a[x1,y] != 0:
                a[x1+1,y] = a[x1,y]
                a[x1,y] = 0
                x1 += 1
            # 防止x1+1溢出,上面up部分,a列表参数可以为负,所以不用管
            if x1 == 3:
                x1 = 2
            if a[x1+1,y] == a[x1,y] and a[x1,y] != 0:
                a[x1+1,y] *= 2
                a[x1,y] = 0
            y += 1
        x -= 1
    i = check_down(a) 
    if i == 0:
        a = add(a)
        i = check_down(a)
    return a,i
def check_down(a):
    i = 1
    x = 2
    while x >= 0:
        y = 0
        while y < 4:
            if a[x,y] == 0 or a[x+1,y] == a[x,y]:
                i = 0
                break
            y += 1
        if i == 0:
            break
        x -= 1
    return i
def left(a):
    y = 1
    while y < 4:
        x = 0
        while x < 4:
            y1 = y
            while a[x,y1-1] == 0 and a[x,y1] != 0 and y1 > 0:
                a[x,y1-1] = a[x,y1]
                a[x,y1] = 0
                y1 -= 1
            if y1 == 0:
                y1 = 1            
            if a[x,y1-1] == a[x,y1] and a[x,y1] != 0:
                a[x,y1-1] *= 2
                a[x,y1] = 0
            x += 1
        y += 1
    i = check_left(a) 
    if i == 0:
        a = add(a)
        i = check_left(a)
    return a,i
def check_left(a):
    i = 1
    y = 1
    while y < 4:
        x = 0
        while x < 4:
            if a[x,y] == 0 or a[x,y-1] == a[x,y]:
                i = 0
                break
            x += 1
        if i == 0:
            break
        y += 1
    return i
def right(a):
    y = 2
    while y >= 0:
        x = 0
        while x < 4:
            y1 = y
            while y1 < 3 and a[x,y1+1] == 0 and a[x,y1] != 0:
                a[x,y1+1] = a[x,y1]
                a[x,y1] = 0
                y1 += 1
            # 防止x1+1溢出,上面up部分,a列表参数可以为负,所以keyi不用管
            if y1 == 3:
                y1 = 2
            if a[x,y1+1] == a[x,y1] and a[x,y1] != 0:
                a[x,y1+1] *= 2
                a[x,y1] = 0
            x += 1
        y -= 1
    i = check_down(a) 
    if i == 0:
        a = add(a)
        i = check_down(a)
    return a,i
def check_down(a):
    i = 1
    y = 2
    while y >= 0:
        x = 0
        while x < 4:
            if a[x,y] == 0 or a[x,y+1] == a[x,y]:
                i = 0
                break
            x += 1
        if i == 0:
            break
        y -= 1
    return i
def check_win():
    i = 0
    x = 0
    while x < 4:
        y = 0
        while y < 4:
            if a[x,y] == 2048:
                i = 1
                break
            y += 1
        if i == 1:
            break
        x += 1
    return i
# ______mian______
a = new_a()
# 测试用
# a = np.asarray([[2,2,2,1024],[2,2,2,1024],[2,2,2,2],[2,2,2,2]])
print_a(a)
while True:
    key = input("上(w),左(a),下(s),右(d)\n新游戏(new),退出(out)\n输入:")
    i = 1
    if key == 'w':
        a,i = up(a)
    elif key == 's':
        a,i = down(a)
    elif key == 'a':
        a,i = left(a)
    elif key == 'd':
        a,i = right(a)
    elif key == 'new':
        a = new_a()
        i = 0
    elif key == 'out':
        print("\n游戏退出")
        break
    else:
        print("\n命令错误,重新输入\n")
        continue
    os.system("cls")
    print_a(a)
    if i == 1:
        print("\nYou are Lost\n游戏结束")
        break
    if check_win():
        print("\nPERFECT\nYou are Win!")
        break

更新1
问题如下:
Python实现2048小游戏
测试时up操作后直接游戏失败
原因
检查可否继续游戏(有空位)的check_null函数和检查可否添加2/4的check_add函数有区别
可否添加check_null只检查是否有空即可
继续游戏check_add检查增加2/4后是否有空位或可否移动
更新代码如下
(check_up等函数后半部分判断多余,统一成check_null函数)

import numpy as np
import random
import os

def print_a(a):
    print(" _______________________")
    x = 0
    while x < 4:
        y = 0
        print("|     |     |     |     |")
        while y < 4:
            if a[x][y] == 0:
                print("|    ",end=" ")
            else:
                print("|%4d"%a[x][y],end=" ")
            y += 1
        print("|\n|_____|_____|_____|_____|")
        x += 1
def new_a():
    a = np.zeros([4,4], dtype = int)
    a[xy()] = 2
    a[xy()] = 2
    return a
def xy():
    x = random.randint(0,3)
    y = random.randint(0,3)
    return x,y
def add(a):
    m = random.randint(0,9)
    while True:
        x,y =xy()
        if a[x,y] == 0:
            if m == 0:
                a[x,y] = 4
            else:
                a[x,y] = 2
            break
    return a
def up(a):
    x = 1
    while x < 4:
        y = 0
        while y < 4:
            x1 = x
            while a[x1-1,y] == 0 and a[x1,y] != 0 and x1 > 0:
                a[x1-1,y] = a[x1,y]
                a[x1,y] = 0
                x1 -= 1
            # a列表参数可以为负,所以不用管
            if x1 == 0:
                x1 = 1            
            if a[x1-1,y] == a[x1,y] and a[x1,y] != 0:
                a[x1-1,y] *= 2
                a[x1,y] = 0
            y += 1
        x += 1
    # 检查是否有空位
    i = check_null(a) 
    if i == 0:
        a = add(a)
        # 检查加入2/4后是否可以继续游戏
        i = check_add(a)
    return a,i
def down(a):
    x = 2
    while x >= 0:
        y = 0
        while y < 4:
            x1 = x
            while x1 < 3 and a[x1+1,y] == 0 and a[x1,y] != 0:
                a[x1+1,y] = a[x1,y]
                a[x1,y] = 0
                x1 += 1
            # 防止x1+1溢出,上面up部分,a列表参数可以为负,所以不用管
            if x1 == 3:
                x1 = 2
            if a[x1+1,y] == a[x1,y] and a[x1,y] != 0:
                a[x1+1,y] *= 2
                a[x1,y] = 0
            y += 1
        x -= 1
    i = check_null(a) 
    if i == 0:
        a = add(a)
        i = check_add(a)
    return a,i
def left(a):
    y = 1
    while y < 4:
        x = 0
        while x < 4:
            y1 = y
            while a[x,y1-1] == 0 and a[x,y1] != 0 and y1 > 0:
                a[x,y1-1] = a[x,y1]
                a[x,y1] = 0
                y1 -= 1
            if y1 == 0:
                y1 = 1            
            if a[x,y1-1] == a[x,y1] and a[x,y1] != 0:
                a[x,y1-1] *= 2
                a[x,y1] = 0
            x += 1
        y += 1
    i = check_null(a) 
    if i == 0:
        a = add(a)
        i = check_add(a)
    return a,i
def right(a):
    y = 2
    while y >= 0:
        x = 0
        while x < 4:
            y1 = y
            while y1 < 3 and a[x,y1+1] == 0 and a[x,y1] != 0:
                a[x,y1+1] = a[x,y1]
                a[x,y1] = 0
                y1 += 1
                # 防止x1+1溢出,上面up部分,a列表参数可以为负,所以keyi不用管
            if y1 == 3:
                y1 = 2
            if a[x,y1+1] == a[x,y1] and a[x,y1] != 0:
                a[x,y1+1] *= 2
                a[x,y1] = 0
            x += 1
        y -= 1
    i = check_null(a) 
    if i == 0:
        a = add(a)
        i = check_add(a)
    return a,i
def check_null(a):
    i = 1
    x = 0
    while x < 4:
        y = 0
        while y < 4:
            if a[x,y] == 0:
                i = 0
                break
            y += 1
        if i != 1:
            break
        x += 1
    return i    
def check_add(a):
    i = 1
    x = 0
    while x < 4:
        y = 0
        while y < 4:
            # 防止溢出
            if x == 0:
                m1,m2 = 1,1
            elif x == 3:
                m1,m2 = -1,-1
            else:
                m1,m2 = 1,-1
            if y == 0:
                n1,n2 = 1,1
            elif y == 3:
                n1,n2 = -1,-1
            else:
                n1,n2 = 1,-1
            # 空位或可相加检查
            if a[x+m1,y] == a[x,y] or a[x+m2,y] == a[x,y] or a[x,y+n1] == a[x,y] or a[x,y+n2] == a[x,y] or a[x,y] == 0:
                i = 0
                break                
            y += 1
        if i == 0:
            break
        x += 1
    return i
def check_win():
    i = 0
    x = 0
    while x < 4:
        y = 0
        while y < 4:
            if a[x,y] == 2048:
                i = 1
                break
            y += 1
        if i == 1:
            break
        x += 1
    return i
# ______mian______
a = new_a()
# 测试用
# a = np.asarray([[256,0,256,1024],[4,256,4,256],[256,4,256,512],[4,256,4,256]])
print_a(a)
while True:
    key = input("上(w),左(a),下(s),右(d)\n新游戏(new),退出(out)\n输入:")
    i = 1
    if key == 'w':
        a,i = up(a)
    elif key == 's':
        a,i = down(a)
    elif key == 'a':
        a,i = left(a)
    elif key == 'd':
        a,i = right(a)
    elif key == 'new':
        a = new_a()
        i = 0
    elif key == 'out':
        print("\n游戏退出")
        break
    else:
        print("\n命令错误,重新输入\n")
        continue
    os.system("cls")
    print_a(a)
    if i == 1:
        print("\nYou are Lost\n游戏结束")
        break
    if check_win():
        print("\nPERFECT\nYou are Win!")
        break

更新2
问题如下:
Python实现2048小游戏
原因
不可down,但是可以left或right,如果输入s应不添加新块且可继续操作
解决方法
把check_add的函数提到if外面了
如果不是空就不添加新的,然后判断是否可相加(继续游戏)
更新代码如下

import numpy as np
import random
import os

def print_a(a):
    print(" _______________________")
    x = 0
    while x < 4:
        y = 0
        print("|     |     |     |     |")
        while y < 4:
            if a[x][y] == 0:
                print("|    ",end=" ")
            else:
                print("|%4d"%a[x][y],end=" ")
            y += 1
        print("|\n|_____|_____|_____|_____|")
        x += 1
def new_a():
    a = np.zeros([4,4], dtype = int)
    a[xy()] = 2
    a[xy()] = 2
    return a
def xy():
    x = random.randint(0,3)
    y = random.randint(0,3)
    return x,y
def add(a):
    m = random.randint(0,9)
    while True:
        x,y =xy()
        if a[x,y] == 0:
            if m == 0:
                a[x,y] = 4
            else:
                a[x,y] = 2
            break
    return a
def up(a):
    x = 1
    while x < 4:
        y = 0
        while y < 4:
            x1 = x
            while a[x1-1,y] == 0 and a[x1,y] != 0 and x1 > 0:
                a[x1-1,y] = a[x1,y]
                a[x1,y] = 0
                x1 -= 1
            # a列表参数可以为负,所以不用管
            if x1 == 0:
                x1 = 1            
            if a[x1-1,y] == a[x1,y] and a[x1,y] != 0:
                a[x1-1,y] *= 2
                a[x1,y] = 0
            y += 1
        x += 1
    # 检查是否有空位
    i = check_null(a) 
    if i == 0:
        a = add(a)
    # 检查加入2/4后是否可以继续游戏
    i = check_add(a)
    return a,i
def down(a):
    x = 2
    while x >= 0:
        y = 0
        while y < 4:
            x1 = x
            while x1 < 3 and a[x1+1,y] == 0 and a[x1,y] != 0:
                a[x1+1,y] = a[x1,y]
                a[x1,y] = 0
                x1 += 1
            # 防止x1+1溢出,上面up部分,a列表参数可以为负,所以不用管
            if x1 == 3:
                x1 = 2
            if a[x1+1,y] == a[x1,y] and a[x1,y] != 0:
                a[x1+1,y] *= 2
                a[x1,y] = 0
            y += 1
        x -= 1
    i = check_null(a) 
    if i == 0:
        a = add(a)
    i = check_add(a)
    return a,i
def left(a):
    y = 1
    while y < 4:
        x = 0
        while x < 4:
            y1 = y
            while a[x,y1-1] == 0 and a[x,y1] != 0 and y1 > 0:
                a[x,y1-1] = a[x,y1]
                a[x,y1] = 0
                y1 -= 1
            if y1 == 0:
                y1 = 1            
            if a[x,y1-1] == a[x,y1] and a[x,y1] != 0:
                a[x,y1-1] *= 2
                a[x,y1] = 0
            x += 1
        y += 1
    i = check_null(a) 
    if i == 0:
        a = add(a)
    i = check_add(a)
    return a,i
def right(a):
    y = 2
    while y >= 0:
        x = 0
        while x < 4:
            y1 = y
            while y1 < 3 and a[x,y1+1] == 0 and a[x,y1] != 0:
                a[x,y1+1] = a[x,y1]
                a[x,y1] = 0
                y1 += 1
            # 防止x1+1溢出,上面up部分,a列表参数可以为负,所以keyi不用管
            if y1 == 3:
                y1 = 2
            if a[x,y1+1] == a[x,y1] and a[x,y1] != 0:
                a[x,y1+1] *= 2
                a[x,y1] = 0
            x += 1
        y -= 1
    i = check_null(a) 
    if i == 0:
        a = add(a)
    i = check_add(a)
    return a,i
def check_null(a):
    i = 1
    x = 0
    while x < 4:
        y = 0
        while y < 4:
            if a[x,y] == 0:
                i = 0
                break
            y += 1
        if i != 1:
            break
        x += 1
    return i    
def check_add(a):
    i = 1
    x = 0
    while x < 4:
        y = 0
        while y < 4:
            # 防止溢出
            if x == 0:
                m1,m2 = 1,1
            elif x == 3:
                m1,m2 = -1,-1
            else:
                m1,m2 = 1,-1
            if y == 0:
                n1,n2 = 1,1
            elif y == 3:
                n1,n2 = -1,-1
            else:
                n1,n2 = 1,-1
            # 空位或可相加检查
            if a[x+m1,y] == a[x,y] or a[x+m2,y] == a[x,y] or a[x,y+n1] == a[x,y] or a[x,y+n2] == a[x,y] or a[x,y] == 0:
                i = 0
                break                
            y += 1
        if i == 0:
            break
        x += 1
    return i
def check_win():
    i = 0
    x = 0
    while x < 4:
        y = 0
        while y < 4:
            if a[x,y] == 2048:
                i = 1
                break
            y += 1
        if i == 1:
            break
        x += 1
    return i
# ______mian______
a = new_a()
# 测试用
# a = np.asarray([[256,0,256,1024],[4,256,4,256],[256,4,256,512],[4,256,4,256]])
print_a(a)
while True:
    key = input("上(w),左(a),下(s),右(d)\n新游戏(new),退出(out)\n输入:")
    i = 1
    if key == 'w':
        a,i = up(a)
    elif key == 's':
        a,i = down(a)
    elif key == 'a':
        a,i = left(a)
    elif key == 'd':
        a,i = right(a)
    elif key == 'new':
        a = new_a()
        i = 0
    elif key == 'out':
        print("\n游戏退出")
        break
    else:
        print("\n命令错误,重新输入\n")
        continue
    os.system("cls")
    print_a(a)
    if i == 1:
        print("\nYou are Lost\n游戏结束")
        break
    if check_win():
        print("\nPERFECT\nYou are Win!")
        break