用Python实现小游戏 填满街区 烧脑小游戏哦

来看一下游戏规则

  • 规则1:每行和每列包含相等数量的蓝色和红色块
  • 规则2:没有相同的行或列。
  • 规则3:相邻的相同块不超过2个。

首先我们导入包 并初始化一下

import pygame,random
from pygame.locals import *
pygame.init()
pygame.mixer.init()
pygame.font.init()

然后我们设置一下基础的一些属性

width = 600
height = 600
bg_color = 130,110,200
WHITE = 255,255,255
BLACK = 0,0,0
BLUE = 0,0,255
RED = 255,0,0
text_color = 70,45,25
text_color_2 = 250,105,65
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("填满街区!")
clock = pygame.time.Clock()
quit = True
# myfont = pygame.font.Font(None, 24)
# myfont18 = pygame.font.Font(None, 18)
# myfont22 = pygame.font.Font(None, 22)
myfont = pygame.font.Font("msyh.ttc", 18)
myfont18 = pygame.font.Font("msyh.ttc", 12)
myfont22 = pygame.font.Font("msyh.ttc", 16)

try_times = 0
locked_list = []
left_margin = 5
history = []
grade = 'easy'

nrows = 6
grid_width = 600/nrows
L = [[-1 for i in range(nrows)] for i in range(nrows)]

定义一些功能

  • 显示函数
def print_text(font, x, y, text, color=BLACK, alpha=0):
    # global screen
    imgText = font.render(text, True, color)
    imgText = imgText.convert_alpha()
    screen.blit(imgText, (x, y))
  • 获取行和列
def get_rows_and_cols():
    global cols,rows
    cols = [[]] * nrows
    rows = [[]] * nrows
    temp_vec = [None] * nrows
    cols = L
    for i in range(nrows):
        temp_vec = [None] * nrows
        for j in range(nrows):
            temp_vec[j] = L[j][i]
        rows[i] = temp_vec

规则判断:

def standard_1():
    for i in range(nrows):
        tv = rows[i]
        if sum(tv) != nrows // 2:
            return 0
        tv = cols[i]
        if sum(tv) != nrows // 2:
            return 0
    return 1

def standard_2():
    if len(set([str(i) for i in rows])) < nrows:
        return 0
    if len(set([str(i) for i in cols])) < nrows:
        return 0
    return 1

def standard_3():
    for i in range(nrows):
        for j in range(nrows):
            if standard_3_unit(i,j) == 0:
                return 0
    return 1

def standard_3_unit(i,j):
    q = 0
    t = L[i][j]
    try:
        if L[i+1][j] == t:
            q += 1
    except:
        pass
    try:
        if L[i-1][j] == t:
            q += 1
    except:
        pass
    try:
        if L[i][j+1] == t:
            q += 1
    except:
        pass
    try:
        if L[i][j-1] == t:
            q += 1
    except:
        pass
    if q >= 3:
        return 0
    else:
        return 1

生成答案

def ini_answer():
    global L

    # 逐行排列解
    labels_list = [k for k in range(nrows)]
    for i in range(nrows):
        labels = random.sample(labels_list,nrows//2)
        for j in range(nrows):
            if i <= nrows//2 - 1:
                if j in labels:
                    L[i][j] = 0
                else:
                    L[i][j] = 1
            else:
                q0 = q1 = 0
                for k in range(nrows):
                    if L[k][j] == 0:
                        q0 += 1
                    if L[k][j] == 1:
                        q1 += 1
                if q0 >= nrows//2:
                    L[i][j] = 1
                    continue
                if q1 >= nrows//2:
                    L[i][j] = 0
                    continue
                if j in labels:
                    L[i][j] = 0
                else:
                    L[i][j] = 1

生成问题

def ini_pro():
    global try_times,grid_width,L,nrows
    SampleList = []

    if grade == 'dif' or nrows <= 5:
        SampleNum = int(nrows ** 2) * 2 // 3
    else:
        SampleNum = int(nrows ** 2) * 1 // 2
    for i in range(nrows):
        for j in range(nrows):
            SampleList.append((i,j))
    HollowList = random.sample(SampleList,SampleNum)

    L = [[-1 for i in range(nrows)] for i in range(nrows)]
    ini_answer()
    get_rows_and_cols()
    grid_width = 600 / nrows
    if standard_1() and standard_2() and standard_3():
        pass
    else:
        while 1:
            try_times += 1
            grid_width = 600 / nrows
            # print("It tried " + str(try_times) + " times!")
            if standard_1() and standard_2() and standard_3():
                print("这个成功!")
                break
            else:
                ini_answer()
                get_rows_and_cols()

            if try_times >= 100000000:
                print("这个失败!")
                break
    for t in HollowList:
        x = t[0]
        y = t[1]
        L[x][y] = -1

游戏主体:

stage = 'menu'
while quit:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit = False
        elif event.type == KEYDOWN:
            if stage == 'menu':
                if event.key == K_s or event.key == K_d or event.key == K_f:
                    nrows = 4
                    if event.key == K_d or event.key == K_f:
                        nrows = 6
                    if event.key == K_d:
                        grade = 'easy'
                    if event.key == K_f:
                        grade = 'dif'
                    ini_pro()
                    stage = 'game'
            elif stage == 'game':
                if event.key == K_r:
                    if history:
                        gp = history[-1]
                        gx = gp[0]
                        gy = gp[1]
                        L[gx][gy] = -1
                        history.pop()
                if event.key == K_ESCAPE:
                    stage = 'menu'
            elif stage == 'win':
                if event.key == K_r:
                    stage = 'menu'
        elif event.type == MOUSEBUTTONDOWN:
            mouse_x, mouse_y = event.pos
            if stage == 'game':
                gx = int(mouse_x // grid_width)
                gy = int(mouse_y // grid_width)
                if event.button == 3 and L[gx][gy] == -1:
                    L[gx][gy] = 1
                    history.append((gx,gy))
                    if standard_1() and standard_2() and standard_3():
                        stage = 'win'
                if event.button == 1 and L[gx][gy] == -1:
                    L[gx][gy] = 0
                    history.append((gx, gy))
                    if standard_1() and standard_2() and standard_3():
                        stage = 'win'

    pygame.draw.rect(screen,bg_color,(0,0,width,height))

    if stage == 'menu':
        # imgText = myfont.render("Fill the blocks !", True, text_color)
        # imgText = imgText.convert_alpha()
        # screen.blit(imgText, (25, 50))
        # imgText = myfont.render("Right click to fill with red & Left click to fill with blue !", True, text_color)
        # imgText = imgText.convert_alpha()
        # screen.blit(imgText, (25, 100))
        print_text(myfont,left_margin,50,"填满街区!",text_color)
        print_text(myfont,left_margin,75,"右击使用红色!",text_color)
        print_text(myfont,left_margin,100,"左击使用蓝色!",text_color)
        print_text(myfont22,left_margin,125,"规则1:每行和每列包含相等数量的蓝色和红色块。",text_color)
        print_text(myfont22,left_margin,150,"规则2:没有相同的行或列。",text_color)
        print_text(myfont22,left_margin,175,"规则3:相邻的相同块不超过2个。",text_color)
        print_text(myfont, left_margin, 225, "按S以4*4开始游戏-简单", text_color_2)
        print_text(myfont, left_margin, 250, "按D键以6*6-正常开始游戏", text_color_2)
        print_text(myfont, left_margin, 275, "按F键以6*6的难度开始游戏", text_color_2)
        print_text(myfont, left_margin, 300, "按R键在游戏中回放", text_color_2)
        print_text(myfont, left_margin, 325, "按ESC重新启动", text_color_2)

    if stage == 'win':
        print_text(myfont, left_margin, 50, "你赢了!", RED)
        print_text(myfont, left_margin, 75, "按R重新开始游戏。", text_color)

    if stage == 'game':
        for i in range(nrows):
            for j in range(nrows):
                if L[i][j] == 0:
                    pygame.draw.rect(screen, BLUE, (grid_width * i, grid_width * j, grid_width, grid_width))
                elif L[i][j] == 1:
                    pygame.draw.rect(screen, RED, (grid_width * i, grid_width * j, grid_width, grid_width))
                elif L[i][j] == -1:
                    pygame.draw.rect(screen, WHITE, (grid_width * i, grid_width * j, grid_width, grid_width))

        for i in range(nrows-1):
            pos = grid_width * (i+1)
            pygame.draw.line(screen, BLACK, (0, pos), (600, pos), 2)
        for i in range(nrows-1):
            pos = grid_width * (i+1)
            pygame.draw.line(screen, BLACK, (pos, 0), (pos, 600), 2)

    #pygame.display.flip()
    pygame.display.update()
    clock.tick(60)
    # screen.blit(1,1)

完整代码如下:

import pygame,random
from pygame.locals import *
pygame.init()
pygame.mixer.init()
pygame.font.init()

width = 600
height = 600
bg_color = 130,110,200
WHITE = 255,255,255
BLACK = 0,0,0
BLUE = 0,0,255
RED = 255,0,0
text_color = 70,45,25
text_color_2 = 250,105,65
screen = pygame.display.set_mode((width,height))
pygame.display.set_caption("填满街区!")
clock = pygame.time.Clock()
quit = True
# myfont = pygame.font.Font(None, 24)
# myfont18 = pygame.font.Font(None, 18)
# myfont22 = pygame.font.Font(None, 22)
myfont = pygame.font.Font("msyh.ttc", 18)
myfont18 = pygame.font.Font("msyh.ttc", 12)
myfont22 = pygame.font.Font("msyh.ttc", 16)

try_times = 0
locked_list = []
left_margin = 5
history = []
grade = 'easy'

nrows = 6
grid_width = 600/nrows
L = [[-1 for i in range(nrows)] for i in range(nrows)]

def print_text(font, x, y, text, color=BLACK, alpha=0):
    # global screen
    imgText = font.render(text, True, color)
    imgText = imgText.convert_alpha()
    screen.blit(imgText, (x, y))

cols = 0
rows = 0
def get_rows_and_cols():
    global cols,rows
    cols = [[]] * nrows
    rows = [[]] * nrows
    temp_vec = [None] * nrows
    cols = L
    for i in range(nrows):
        temp_vec = [None] * nrows
        for j in range(nrows):
            temp_vec[j] = L[j][i]
        rows[i] = temp_vec

def standard_1():
    for i in range(nrows):
        tv = rows[i]
        if sum(tv) != nrows // 2:
            return 0
        tv = cols[i]
        if sum(tv) != nrows // 2:
            return 0
    return 1

def standard_2():
    if len(set([str(i) for i in rows])) < nrows:
        return 0
    if len(set([str(i) for i in cols])) < nrows:
        return 0
    return 1

def standard_3():
    for i in range(nrows):
        for j in range(nrows):
            if standard_3_unit(i,j) == 0:
                return 0
    return 1

def standard_3_unit(i,j):
    q = 0
    t = L[i][j]
    try:
        if L[i+1][j] == t:
            q += 1
    except:
        pass
    try:
        if L[i-1][j] == t:
            q += 1
    except:
        pass
    try:
        if L[i][j+1] == t:
            q += 1
    except:
        pass
    try:
        if L[i][j-1] == t:
            q += 1
    except:
        pass
    if q >= 3:
        return 0
    else:
        return 1

def ini_answer():
    global L

    # 逐行排列解
    labels_list = [k for k in range(nrows)]
    for i in range(nrows):
        labels = random.sample(labels_list,nrows//2)
        for j in range(nrows):
            if i <= nrows//2 - 1:
                if j in labels:
                    L[i][j] = 0
                else:
                    L[i][j] = 1
            else:
                q0 = q1 = 0
                for k in range(nrows):
                    if L[k][j] == 0:
                        q0 += 1
                    if L[k][j] == 1:
                        q1 += 1
                if q0 >= nrows//2:
                    L[i][j] = 1
                    continue
                if q1 >= nrows//2:
                    L[i][j] = 0
                    continue
                if j in labels:
                    L[i][j] = 0
                else:
                    L[i][j] = 1

def ini_pro():
    global try_times,grid_width,L,nrows
    SampleList = []

    if grade == 'dif' or nrows <= 5:
        SampleNum = int(nrows ** 2) * 2 // 3
    else:
        SampleNum = int(nrows ** 2) * 1 // 2
    for i in range(nrows):
        for j in range(nrows):
            SampleList.append((i,j))
    HollowList = random.sample(SampleList,SampleNum)

    L = [[-1 for i in range(nrows)] for i in range(nrows)]
    ini_answer()
    get_rows_and_cols()
    grid_width = 600 / nrows
    if standard_1() and standard_2() and standard_3():
        pass
    else:
        while 1:
            try_times += 1
            grid_width = 600 / nrows
            # print("It tried " + str(try_times) + " times!")
            if standard_1() and standard_2() and standard_3():
                print("这个成功!")
                break
            else:
                ini_answer()
                get_rows_and_cols()

            if try_times >= 100000000:
                print("这个失败!")
                break
    for t in HollowList:
        x = t[0]
        y = t[1]
        L[x][y] = -1
# print(rows)
# print(cols)

stage = 'menu'
while quit:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit = False
        elif event.type == KEYDOWN:
            if stage == 'menu':
                if event.key == K_s or event.key == K_d or event.key == K_f:
                    nrows = 4
                    if event.key == K_d or event.key == K_f:
                        nrows = 6
                    if event.key == K_d:
                        grade = 'easy'
                    if event.key == K_f:
                        grade = 'dif'
                    ini_pro()
                    stage = 'game'
            elif stage == 'game':
                if event.key == K_r:
                    if history:
                        gp = history[-1]
                        gx = gp[0]
                        gy = gp[1]
                        L[gx][gy] = -1
                        history.pop()
                if event.key == K_ESCAPE:
                    stage = 'menu'
            elif stage == 'win':
                if event.key == K_r:
                    stage = 'menu'
        elif event.type == MOUSEBUTTONDOWN:
            mouse_x, mouse_y = event.pos
            if stage == 'game':
                gx = int(mouse_x // grid_width)
                gy = int(mouse_y // grid_width)
                if event.button == 3 and L[gx][gy] == -1:
                    L[gx][gy] = 1
                    history.append((gx,gy))
                    if standard_1() and standard_2() and standard_3():
                        stage = 'win'
                if event.button == 1 and L[gx][gy] == -1:
                    L[gx][gy] = 0
                    history.append((gx, gy))
                    if standard_1() and standard_2() and standard_3():
                        stage = 'win'

    pygame.draw.rect(screen,bg_color,(0,0,width,height))

    if stage == 'menu':
        # imgText = myfont.render("Fill the blocks !", True, text_color)
        # imgText = imgText.convert_alpha()
        # screen.blit(imgText, (25, 50))
        # imgText = myfont.render("Right click to fill with red & Left click to fill with blue !", True, text_color)
        # imgText = imgText.convert_alpha()
        # screen.blit(imgText, (25, 100))
        print_text(myfont,left_margin,50,"填满街区!",text_color)
        print_text(myfont,left_margin,75,"右击使用红色!",text_color)
        print_text(myfont,left_margin,100,"左击使用蓝色!",text_color)
        print_text(myfont22,left_margin,125,"规则1:每行和每列包含相等数量的蓝色和红色块。",text_color)
        print_text(myfont22,left_margin,150,"规则2:没有相同的行或列。",text_color)
        print_text(myfont22,left_margin,175,"规则3:相邻的相同块不超过2个。",text_color)
        print_text(myfont, left_margin, 225, "按S以4*4开始游戏-简单", text_color_2)
        print_text(myfont, left_margin, 250, "按D键以6*6-正常开始游戏", text_color_2)
        print_text(myfont, left_margin, 275, "按F键以6*6的难度开始游戏", text_color_2)
        print_text(myfont, left_margin, 300, "按R键在游戏中回放", text_color_2)
        print_text(myfont, left_margin, 325, "按ESC重新启动", text_color_2)

    if stage == 'win':
        print_text(myfont, left_margin, 50, "你赢了!", RED)
        print_text(myfont, left_margin, 75, "按R重新开始游戏。", text_color)

    if stage == 'game':
        for i in range(nrows):
            for j in range(nrows):
                if L[i][j] == 0:
                    pygame.draw.rect(screen, BLUE, (grid_width * i, grid_width * j, grid_width, grid_width))
                elif L[i][j] == 1:
                    pygame.draw.rect(screen, RED, (grid_width * i, grid_width * j, grid_width, grid_width))
                elif L[i][j] == -1:
                    pygame.draw.rect(screen, WHITE, (grid_width * i, grid_width * j, grid_width, grid_width))

        for i in range(nrows-1):
            pos = grid_width * (i+1)
            pygame.draw.line(screen, BLACK, (0, pos), (600, pos), 2)
        for i in range(nrows-1):
            pos = grid_width * (i+1)
            pygame.draw.line(screen, BLACK, (pos, 0), (pos, 600), 2)

    #pygame.display.flip()
    pygame.display.update()
    clock.tick(60)
    # screen.blit(1,1)

效果图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一起学习python,小白指导,教学分享记得私信我

猜你喜欢

转载自blog.csdn.net/Miku_wx/article/details/113113867