Python笔记相关(中)

简介: Python笔记相关

Python笔记相关(上):https://developer.aliyun.com/article/1488574


获取时间及星期

from datetime import *
print(datetime.today().strftime("%H:%M:%S %Y-%m-%d"))
week = ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"]
print(week[datetime.today().weekday()])


分类计数输入的字符串

str = input("随便输点吧:")
ls = list(str)
nums = 0
chars = 0
kong = 0
tems = 0
for s in ls:
    a = ord(s)
    if a >= 48 and a <= 57:
        nums += 1
    elif a >= 65 and a <= 90 or a>=97 and a <=122:
        chars += 1
    elif a == 32:
        kong += 1
    else:
        tems += 1
print(ls)
print("数字个数:%d,字母个数:%d,空格数:%d,其他字符:%d" % (nums, chars, kong, tems))


abs()函数

import turtle as t
t.forward(1)
t.lt(90)
t.fd(1)
print(t.pos())
print(abs(t.pos()))

输出:

(1.00,1.00)
1.4142135623730951

进步

from math import *
def jbtb(j, t):
    min = 10
    for i in range(1, 366):  # 进步i天
        A = fabs(pow((1 + j), i) * pow((1 - t), (365 - i)) - 1)
        if A < min:
            min = A
            x = i
            y = 365 - i
    print("当进步%d天,退步%d天时,最接近" % (x, y))
    print("最接近的值为{}".format(pow((1 + 0.02), x) * pow((1 - 0.01), y)))
    print(min)
a = eval(input("请输入进步加的:"))
b = eval(input("请输入退步加的:"))
jbtb(a, b)

输出:

请输入进步加的:0.02
请输入退步加的:0.01
当进步123天,退步242天时,最接近
最接近的值为1.003548160754847
0.003548160754847096

列表的升序与降序

s = [5, 3, 18, 9,11]
s.sort()
print(s)
s.reverse()
print(s)

输出:

[3, 5, 9, 11, 18]
[18, 11, 9, 5, 3]

递归与阶乘


递归: 例: 5! (5的递归)

5!=1 * 2 * 3 * 4 * 5

sums=1
def computation(degital):
    global sums
    sums =sums * degital
    if degital == 1:
        return sums
    else:
        return computation(degital - 1)
c=eval(input("请输入一个数,计算阶乘:"))
print(computation(c))

想明白!!!

当 为 1的时候,return 1。

当递归到1的时候,返回1于之一乘,得到结果。否则会无限循环下去。

def computation(degital):
    if degital == 1:
        return 1
    else:
        return computation(degital - 1) * degital
c = eval(input("请输入一个数,计算阶乘:"))
print(computation(c))

递归与斐波那契数列

def rabbit(month):
    if month <= 1:  #1或0时,返回1
        return 1
    else:
        return rabbit(month - 1) + rabbit(month - 2)
lists = []
for i in range(10):
    lists.append(rabbit(i))
print(lists)

输出:

[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

验证码生成


增加要求:

1、首位不能为数字

2、必须同时含有小写字母、大写字母和数字

思路:循环生成每位验证码,第一次循环即是首位,让其从大写字母和小写字母中选一.

同时拥有:可以随机生成出验证码后,给予判断,是否满足条件,满足输出,不满足再重新调用.直到满足为止.

from random import *
def drawCode():
    count1 = 0
    count2 = 0
    count3 = 0
    codeList = []
    for i in range(3):
        if i == 0:
            state = randint(1, 2)
            if state == 1:
                count1 += 1
                f = randint(65, 90)
                A = chr(f)
                codeList.append(A)
            elif state == 2:
                count2 += 1
                s = randint(97, 122)
                a = chr(s)
                codeList.append(a)
        else:
            state = randint(1, 3)
            if state == 1:
                count1 += 1
                f = randint(65, 90)
                A = chr(f)
                codeList.append(A)
            elif state == 2:
                count2 += 1
                s = randint(97, 122)
                a = chr(s)
                codeList.append(a)
            elif state == 3:
                count3 += 1
                t = randint(0, 9)
                num = str(t)
                codeList.append(num)
    if count1 == 0 or count2 == 0 or count3 == 0:
        list.clear(codeList)
        drawCode()
    else:
        CheckCode = "".join(codeList)
        print(CheckCode)
for i in range(10):
    drawCode()

读取文件计词(jieba中文模块)


三国演义

import jieba
txt = open(r"C:\Users\Administrator\Desktop\三国演义.txt", "rb").read()
excludes = {"却说", "将军", "二人", "商议", "不可"}
words = jieba.lcut(txt)
counts = {}
for word in words:
    if len(word) == 1:
        continue
    elif word == "诸葛亮":
        rword = "孔明"
    elif word == "曹贼":
        rword = "曹操"
    else:
        rword = word
    counts[rword] = counts.get(rword, 0) + 1
for word in excludes:
    del counts[word]
items = list(counts.items())
items.sort(key=lambda x: x[1], reverse=True)
for i in range(20):
    word, count = items[i]
    print("{0:5}{1:5}次".format(word, count))

水浒传

import jieba
txt = open(r"C:\Users\Administrator\Desktop\水浒传.txt", "rb").read()
excludes = {"两个", "一个", "只见", "如何", "那里", "哥哥", "说道", "众人", "头领", "这里", "兄弟", "出来", "小人", "这个", "今日"}
words = jieba.lcut(txt)
counts = {}
for word in words:
    if len(word) == 1:
        continue
    elif word == "黑鬼":
        rword = "李逵"
    else:
        rword = word
    counts[rword] = counts.get(rword, 0) + 1
for word in excludes:
    del counts[word]
items = list(counts.items())
items.sort(key=lambda x: x[1], reverse=True)
for i in range(108):
    word, count = items[i]
    print("{0:5}{1:5}次".format(word, count))

字典操作

dict_demo = {"k1": "v1", "k2": "v2", "k3": "v3"}
print(dict_demo.keys())  //获取所有键
print(dict_demo.values())  //获取所有值
print(dict_demo.items())  //获取所有键值
dict_demo["k4"] = "v4"  //添加 k4 = v4
dict_demo["k5"] = "v6"
print(dict_demo.items())  
dict_demo["k5"] = "v5"  //将键为k5的值更改为v5
print(dict_demo.items())  
print(dict_demo.clear())  //清空字典

删除列表中重复的值

import random as r
N_list = []
N = eval(input("请输入N(小于1000):"))
for i in range(N):
    N_list.append(r.randint(1, 1000))
N_list.sort()
print(N_list)
L_list = []
for n in range(1000):
    if n in N_list:
        L_list.append(n)
print(L_list)

数字转换为汉字字符

num = input("输入数字:")
n_List = list(num)
rn_List = []
for n in n_List:
    if n == "1":
        rn = "壹"
    elif n == "2":
        rn = "贰"
    elif n == "3":
        rn = "三"
    elif n == "4":
        rn = "肆"
    elif n == "5":
        rn = "伍"
    elif n == "6":
        rn = "六"
    elif n == "7":
        rn = "七"
    elif n == "8":
        rn = "八"
    elif n == "9":
        rn = "九"
    elif n == ".":
        rn = "点"
    rn_List.append(rn)
print("".join(rn_List))
//输入数字:1.23
//壹点贰三

随机生成8个0~10之间不相同的数

import random as r
N_List = []
def rom():
    N = r.randint(0, 10)
    if N in N_List:
        rom()
    else:
        N_List.append(N)
for i in range(8):
    rom()
print(N_List)
//[8, 10, 3, 2, 5, 7, 1, 0]

游戏模块

import pygame
# 窗口宽高
WINWIDTH = 640
WINHEIGHT = 480
# 颜色设置
DARKTURQUOISE = (3, 54, 73)
YELLOW = (255, 255, 193)
GRAY = (128, 128, 128)
# 颜色变量
BGCOLOR = DARKTURQUOISE
MSGCOLOR = DARKTURQUOISE
MSGBGCOLOR = YELLOW
BTCOLOR = YELLOW
BTTEXTCOLOR = GRAY
# 初始化帧率
FPS = 60
# 定义矩形边长
BLOCKSIZE = 60
def main():
    pygame.init()  # 初始化模块
    WINSET = pygame.display.set_mode((WINWIDTH, WINHEIGHT))  # 创建窗体
    WINSET.fill(BGCOLOR)  # 填充颜色
    pygame.display.set_caption('数字推盘')  # 设置标题
    image = pygame.image.load('bg1.jpg')  # 加载图片
    WINSET.blit(image, (0, 0))  # 绘制图片
    BASICFONT = pygame.font.Font('STKAITI.TTF', 25)  # 创建字体对象
    msgSurf = BASICFONT.render('初始化。。。', True, MSGCOLOR, MSGBGCOLOR)  # 渲染
    WINSET.blit(msgSurf, (0, 0))
    autoSurf = BASICFONT.render('自动', True, BTTEXTCOLOR, BTCOLOR)
    autoRect = autoSurf.get_rect()  # 获取矩形属性
    autoRect.x = WINWIDTH - autoRect.width - 10  # 横坐标
    autoRect.y = WINHEIGHT - autoRect.height - 10  # 纵坐标
    WINSET.blit(autoSurf, autoRect)  # 绘制字体
    # 绘制矩形
    blockRect = pygame.Rect(0.5 * (WINWIDTH - BLOCKSIZE), 0.5 * (WINHEIGHT - BLOCKSIZE), BLOCKSIZE, BLOCKSIZE)
    pygame.draw.rect(WINSET, BTCOLOR, blockRect)
    # 绘制数字
    numSurf = BASICFONT.render('5', True, BTTEXTCOLOR, BTCOLOR)
    numRect = numSurf.get_rect()
    numRect.x = blockRect.x + 0.5 * (BLOCKSIZE - numRect.width)
    numRect.y = blockRect.y + 0.5 * (BLOCKSIZE - numRect.height)
    baseSurf = WINSET.copy()  # 背景
    FPSCLOCK = pygame.time.Clock()  # 创建Clock对象
    for i in range(0, BLOCKSIZE, 2):
        FPSCLOCK.tick(FPS)  # 设置帧率
        pygame.draw.rect(WINSET, BTCOLOR, blockRect)
        WINSET.blit(numSurf, numRect)
        pygame.display.update()  # 窗口刷新
        blockRect.x += 10  # 修改坐标,让其向右移动
        numRect.x += 10
        WINSET.blit(baseSurf, (0, 0))  # 备份baseSurf覆盖WINSET
    pygame.quit()  # 模块卸载
if __name__ == '__main__':
    main()

测试版10/15/23/02

import pygame, random, sys
from pygame.locals import *
from define import *
from pygame import K_ESCAPE, KEYUP, QUIT, MOUSEBUTTONUP
# 初始化窗口宽高
WINWIDTH = 640
WINHEIGHT = 480
# 初始化推盘行列和空格
ROW = 3
COL = 3
BLANK = None
# 颜色预设
DARKGRAY = (60, 60, 60)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 193)
GRAY = (128, 128, 128)
BRIGHTBLUE = (138, 228, 221)
# 颜色变量
BLANKCOLOR = DARKGRAY
MSGCOLOR = WHITE
BTCOLOR = YELLOW
BTTEXTCOLOR = GRAY
BDCOLOR = BRIGHTBLUE
# 静态常量
BLOCKSIZE = 80
FPS = 60
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
NEWGAME = 'newgame'
AUTOMOVE = random.randint(50, 100)  # 随机移动次数
# 文本对象创建
def makeText(text, tColor, btColor, top, left):
    textSurf = BASICFONT.render(text, True, tColor, btColor)
    textRect = textSurf.get_rect()
    textRect.topleft = (top, left)
    return textSurf, textRect
# 绘制方块在窗口(tilex,tiley)处
def drawTile(tilex, tiley, number, adjx=0, adjy=0):
    left, top = getLeftTopOfTile(tilex, tiley)
    pygame.draw.rect(WINSET, BTCOLOR, (left + adjx, top + adjy, BLOCKSIZE, BLOCKSIZE))
    textSurf = BASICFONT.render(str(number), True, BTTEXTCOLOR)
    textRect = textSurf.get_rect()
    textRect.center = left + int(BLOCKSIZE / 2) + adjx, top + int(BLOCKSIZE / 2) + adjy
    WINSET.blit(textSurf, textRect)
# 计算方块距离窗口原点纵横坐标距离
def getLeftTopOfTile(tilex, tiley):
    xMargin = int((WINWIDTH - (BLOCKSIZE * COL + (COL - 1))) / 2)
    yMargin = int((WINWIDTH - (BLOCKSIZE * ROW + (ROW - 1))) / 2)
    left = xMargin + (tilex * BLOCKSIZE) + (tilex - 1)
    top = yMargin + (tiley * BLOCKSIZE) + (tiley - 1)
    return left, top
# 静态界面绘制
def darwStaticWin():
    winSet = pygame.display.set_mode((WINWIDTH, WINHEIGHT))
    pygame.display.set_caption('数字华容道')
    image = pygame.image.load('bg.jpg')
    winSet.blit(image, (0, 0))
    # 按钮创建
    new_surf, new_rect = makeText('新游戏', BTTEXTCOLOR, BTCOLOR, WINWIDTH - 85, WINHEIGHT - 40)
    winSet.blit(new_surf, new_rect)
    return winSet, new_surf, new_rect
# 动态界面绘制
def drawBoard(board, msg):
    WINSET.blit(STATICSURF, (0, 0))
    if msg:
        msgSurf, msgRect = makeText(msg, MSGCOLOR, None, 5, 5)
        pygame.image.save(msgSurf, 'msg.png')
        imgSurf = pygame.image.load('msg.png')
        WINSET.blit(imgSurf, msgRect)
    for i in range(len(board)):
        for j in range(len(board[0])):
            if board[i][j]:
                drawTile(i, j, board[i][j])
    left, top = getLeftTopOfTile(0, 0)
    width = COL * BLOCKSIZE
    height = ROW * BLOCKSIZE
    pygame.draw.rect(WINSET, BDCOLOR, (left - 5, top - 5, width + 11, height + 11), 4)
# 生成推盘序列
def getStartingBoard():
    initBoard = []
    for i in range(COL):
        i = i + 1
        colum = []
        for j in range(ROW):
            colum.append(i)
            i += COL  # 按列添加,非顺序添加
        initBoard.append(colum)
    initBoard[ROW - 1][COL - 1] = BLANK
    return initBoard
# 移动交换元素位置
def makeMove(board, move):
    blankx, blanky = getBlankPosition(board)
    if move == UP:
        board[blankx][blanky], board[blankx][blanky + 1] = board[blankx][blanky + 1], board[blankx][blanky]
    elif move == DOWN:
        board[blankx][blanky], board[blankx][blanky - 1] = board[blankx][blanky - 1], board[blankx][blanky]
    elif move == LEFT:
        board[blankx][blanky], board[blankx + 1][blanky] = board[blankx + 1][blanky], board[blankx][blanky]
    elif move == RIGHT:
        board[blankx][blanky], board[blankx - 1][blanky] = board[blankx - 1][blanky], board[blankx][blanky]
# 移动的动画效果
def slideAnimation(board, direction, msg, animationSpeed):
    blankx, blanky = getBlankPosition(board)  # 获取空格的行列坐标
    # 获取被移动的方块所在的行列
    if direction == UP:
        movex = blankx
        movey = blanky + 1
    elif direction == DOWN:
        movex = blankx
        movey = blanky - 1
    elif direction == LEFT:
        movex = blankx + 1
        movey = blanky
    elif direction == RIGHT:
        movex = blankx - 1
        movey = blanky
    drawBoard(board, msg)
    BASESURF = WINSET.copy()  # 复制此刻背景作为Surface对象
    # 绘制空白快
    moveLeft, moveTop = getLeftTopOfTile(movex, movey)
    pygame.draw.rect(BASESURF, BLANKCOLOR, (moveLeft, moveTop, BLOCKSIZE, BLOCKSIZE))
    # 连续绘制被移动的方块
    for i in range(0, BLOCKSIZE, animationSpeed):
        checkForQuit()
        WINSET.blit(BASESURF, (0, 0))
        if direction == UP:
            drawTile(movex, movey, board[movex][movey], 0, -i)
        if direction == DOWN:
            drawTile(movex, movey, board[movex][movey], 0, i)
        if direction == LEFT:
            drawTile(movex, movey, board[movex][movey], -i, 0)
        if direction == RIGHT:
            drawTile(movex, movey, board[movex][movey], i, 0)
        pygame.display.update()  # 更新界面
        FPSCLOCK.tick(FPS)  # 控制帧率
# 判断无效移动
def isValidMove(board, direction):
    blankx, blanky = getBlankPosition(board)
    if blankx == 1 and direction == DOWN:
        return False
    elif blankx == 3 and direction == UP:
        return False
    elif blanky == 1 and direction == RIGHT:
        return False
    elif blanky == 3 and direction == LEFT:
        return False
    else:
        return True
# 获取随机移动的方向
def getRandomMove(board, lastMove=None):
    validMoves = [UP, DOWN, LEFT, RIGHT]
    if lastMove == UP or not isValidMove(board, DOWN):
        validMoves.remove(DOWN)
    if lastMove == DOWN or not isValidMove(board, UP):
        validMoves.remove(UP)
    if lastMove == LEFT or not isValidMove(board, RIGHT):
        validMoves.remove(RIGHT)
    if lastMove == RIGHT or not isValidMove(board, LEFT):
        validMoves.remove(LEFT)
    return random.choice(validMoves)
# 初始化推盘
def generateNewPuzzle(numSlides):
    mianBoard = getStartingBoard()  # 获取拼图
    drawBoard(mianBoard, '')
    lastMove = None
    for i in range(numSlides):
        move = getRandomMove(mianBoard, lastMove)
        slideAnimation(mianBoard, move, '初始化...', animationSpeed=int(BLOCKSIZE / 3))
        makeMove(mianBoard, move)
        lastMove = move
    return mianBoard
def getBlankPosition(board):
    for x in range(COL):
        for y in range(ROW):
            if board[x][y] == BLANK:
                return (x, y)
def getSpotClicked(board, x, y):
    for tilex in range(len(board)):
        for tiley in range(len(board[0])):
            left, top = getLeftTopOfTile(tilex, tiley)
            tileRect = pygame.Rect(left, top, BLOCKSIZE, BLOCKSIZE)
            if tileRect.collidepoint(x, y):  # 如果产生碰撞
                return tilex, tiley  # 返回行列
    return None, None
# 获取用户输入
def getInput(mainBoard):
    events = pygame.event.get()
    userInput = None
    for event in events:
        if event.type == MOUSEBUTTONUP:
            # 获取位置关系
            spotx, spoty = getSpotClicked(mainBoard, event.pos[0], event.pos[1])
            # 坐标不在拼图区域,点击的新游戏
            if (spotx, spoty) == (None, None) and NEW_RECT.collidepoint(event.pos):
                userInput = NEWGAME
            else:
                # 如果已完成,点击非选项时不移动
                if mainBoard == getStartingBoard():
                    break
                # 点击位置是否在BLANK旁边
                blankx, blanky = getBlankPosition(mainBoard)
                if spotx == blankx + 1 and spoty == blanky:
                    userInput == LEFT  # 设置移动方向
                elif spotx == blankx - 1 and spoty == blanky:
                    userInput = RIGHT
                elif spotx == blankx and spoty == blanky + 1:
                    userInput = UP
                elif spotx == blankx and spoty == blanky - 1:
                    userInput = DOWN
    return userInput
# 对用户输入进行处理
def processing(userInput, mainBoard, msg):
    if mainBoard == getStartingBoard():
        msg = '完成'
    else:
        msg = '通过鼠标移动方块'
    if userInput:
        # 功能按钮
        if userInput == NEWGAME:
            initBoard = getStartingBoard()
            mainBoard = generateNewPuzzle(numSlides)
        else:
            # 方块移动
            slideAnimation(mainBoard, userInput, msg, 8)
            makeMove(mainBoard, userInput)
    return mainBoard, msg
# 资源回收与程序退出
def terminate():
    pygame.quit()
    sys.exit()
# 退出判断
def checkForQuit():
    for event in pygame.event.get(QUIT):  # 获取所有可能会导致退出的事件
        terminate()  # 执行退出
    for event in pygame.event.get(KEYUP):  # 按下ESC键退出
        if event.key == K_ESCAPE:
            terminate()
        pygame.event.post(event)  # 发送事件至消息列队
def main():
    # FPSCLOCK Clock对象
    # WINSET 窗体Surface对象
    # STATICSURF 静态窗体Surface对象
    # BASICFONT 字体对象
    # NEW_SURF "新游戏"Surface对象,一张内容为文字的图片  调用字体对象的render()方法,渲染为Surface对象显示
    # NEW_RECT get_rect()方法获取的"新游戏"矩形属性
    global FPSCLOCK, WINSET, STATICSURF, BASICFONT  # 定义全局变量
    global NEW_SURF, NEW_RECT
    pygame.init()
    FPSCLOCK = pygame.time.Clock()  # 创建一个Clock对象,并使用变量FPSCLOCK保存
    BASICFONT = pygame.font.Font('STKAITI.TTF', 25)  # 定义返回一个字体对象,并使用变量BASICFONT保存
    WINSET, NEW_SURF, NEW_RECT = darwStaticWin()  # 创建静态窗口
    STATICSURF = WINSET.copy()  # 复制一个静态窗口作为底板
    mainBoard = generateNewPuzzle(AUTOMOVE)  # 初始化
    msg = None 
    while True:
        FPSCLOCK.tick(FPS)  # 设置帧率
        drawBoard(mainBoard, msg)  # 动态界面绘制
        pygame.display.update()
        checkForQuit()  # 判断是否终止
        userInput = getInput(mainBoard)  # 获取输入
        mainBoard, msg = processing(userInput, mainBoard, msg)  # 输入处理
if __name__ == '__main__':
    main()

测试10/1

import pygame, random, sys
from pygame.locals import *
from define import *
# 初始化窗口宽高
WINWIDTH = 640
WINHEIGHT = 480
# 初始化推盘行列和空格
ROW = 3
COL = 3
BLANK = None
# 颜色预设
DARKGRAY = (60, 60, 60)
WHITE = (255, 255, 255)
YELLOW = (255, 255, 193)
GRAY = (128, 128, 128)
BRIGHTBLUE = (138, 228, 221)
# 颜色变量
BLANKCOLOR = DARKGRAY
MSGCOLOR = WHITE
BTCOLOR = YELLOW
BTTEXTCOLOR = GRAY
BDCOLOR = BRIGHTBLUE
# 静态常量
BLOCKSIZE = 80  # 方块大小
FPS = 60  # 帧率
# 按键事件
UP = 'up'
DOWN = 'down'
LEFT = 'left'
RIGHT = 'right'
NEWGAME = 'newgame'
# 随机移动次数
AUTOMOVE = random.randint(50, 100)
# AUTOMOVE = 80
# 文本对象创建
def makeText(text, tColor, btColor, top, left):
    textSurf = BASICFONT.render(text, True, tColor, btColor)
    textRect = textSurf.get_rect()
    textRect.topleft = (top, left)
    return textSurf, textRect  # 将字体渲染的Surface对象,Surface对象的矩形属性
# 绘制方块在窗口(tilex,tiley)处,adjx与adjy为偏移量,可选参数默认值为0
def drawTile(tilex, tiley, number, adjx=0, adjy=0):
    left, top = getLeftTopOfTile(tilex, tiley)
    # 绘制方块
    pygame.draw.rect(WINSET, BTCOLOR, (left + adjx, top + adjy, BLOCKSIZE, BLOCKSIZE))
    # 将数字number渲染到方块上
    textSurf = BASICFONT.render(str(number), True, BTTEXTCOLOR)
    # 获取矩形属性
    textRect = textSurf.get_rect()
    # print(textRect)
    textRect.center = left + int(BLOCKSIZE / 2) + adjx, top + int(BLOCKSIZE / 2) + adjy
    # print(textRect.center)
    # print(textRect)
    # 绘制到静态窗口上
    WINSET.blit(textSurf, textRect)
# 计算方块左上角 距离窗口原点纵横坐标距离
def getLeftTopOfTile(tilex, tiley):
    # 先计算左上角方块的距离
    xMargin = int((WINWIDTH - (BLOCKSIZE * COL + (COL - 1))) / 2)  # 199
    yMargin = int((WINHEIGHT - (BLOCKSIZE * ROW + (ROW - 1))) / 2)  # 119
    # print(xMargin,yMargin)
    # print(tilex, tiley) ?
    left = xMargin + (tilex * BLOCKSIZE) + (tilex - 1)
    top = yMargin + (tiley * BLOCKSIZE) + (tiley - 1)
    # print(left, top)
    return left, top
# 静态界面绘制
def darwStaticWin():
    winSet = pygame.display.set_mode((WINWIDTH, WINHEIGHT))
    pygame.display.set_caption('数字华容道')
    image = pygame.image.load('bg.jpg')
    winSet.blit(image, (0, 0))
    # 按钮创建
    new_surf, new_rect = makeText('新游戏', BTTEXTCOLOR, BTCOLOR, WINWIDTH - 85, WINHEIGHT - 40)
    winSet.blit(new_surf, new_rect)
    return winSet, new_surf, new_rect
# 动态界面绘制
def drawBoard(board, msg):
    # board 推盘列表
    WINSET.blit(STATICSURF, (0, 0))
    if msg:
        msgSurf, msgRect = makeText(msg, MSGCOLOR, None, 5, 5)
        pygame.image.save(msgSurf, 'msg.png')  # 将msgSurf存为名为msg.png的图片
        imgSurf = pygame.image.load('msg.png')  # 加载图片
        # print(msgRect)  # <rect(5, 5, 87, 28)>  矩形属性
        WINSET.blit(imgSurf, msgRect)
    for i in range(len(board)):  # 3
        for j in range(len(board[0])):  # 3
            if board[i][j]:  # 遍历出不为None的
                # print(board[i][j])
                drawTile(i, j, board[i][j])  # 方块上的数字和所在的行列,绘制方块及数字
    # 绘制外边框
    left, top = getLeftTopOfTile(0, 0)  # 198 118
    width = COL * BLOCKSIZE  # 240
    height = ROW * BLOCKSIZE  # 240
    pygame.draw.rect(WINSET, BDCOLOR, (left - 5, top - 5, width + 11, height + 11), 4)  # 外沿厚度4
# 生成推盘序列
def getStartingBoard():
    initBoard = []  # 二维列表
    for i in range(COL):  # 列
        i = i + 1
        colum = []
        for j in range(ROW):
            colum.append(i)
            i += COL  # 按列添加,非顺序添加
        initBoard.append(colum)
    initBoard[ROW - 1][COL - 1] = BLANK  # 最后一位添加None空格
    # print(initBoard)
    return initBoard
# 初始化推盘,随机移动numSlides(50~100)次
def generateNewPuzzle(numSlides):
    mianBoard = getStartingBoard()  # 获取拼图列表
    drawBoard(mianBoard, '')
    lastMove = None
    for i in range(numSlides):
        move = getRandomMove(mianBoard, lastMove)  # 获取随机移动的方向
        slideAnimation(mianBoard, move, '初始化...', int(BLOCKSIZE / 3))
        makeMove(mianBoard, move)
        lastMove = move
    return mianBoard
# 移动交换元素位置
def makeMove(board, move):
    blankx, blanky = getBlankPosition(board)
    if move == UP:
        board[blankx][blanky], board[blankx][blanky + 1] = board[blankx][blanky + 1], board[blankx][blanky]
    elif move == DOWN:
        board[blankx][blanky], board[blankx][blanky - 1] = board[blankx][blanky - 1], board[blankx][blanky]
    elif move == LEFT:
        board[blankx][blanky], board[blankx + 1][blanky] = board[blankx + 1][blanky], board[blankx][blanky]
    elif move == RIGHT:
        board[blankx][blanky], board[blankx - 1][blanky] = board[blankx - 1][blanky], board[blankx][blanky]
# 移动的动画效果
def slideAnimation(board, direction, msg, animationSpeed):
    blankx, blanky = getBlankPosition(board)  # 获取空格的行列坐标
    # 获取被移动的方块所在的行列
    if direction == UP:
        movex = blankx
        movey = blanky + 1
    elif direction == DOWN:
        movex = blankx
        movey = blanky - 1
    elif direction == LEFT:
        movex = blankx + 1
        movey = blanky
    elif direction == RIGHT:
        movex = blankx - 1
        movey = blanky
    drawBoard(board, msg)
    BASESURF = WINSET.copy()  # 复制此刻背景作为Surface对象
    # 绘制空白块
    moveLeft, moveTop = getLeftTopOfTile(movex, movey)
    pygame.draw.rect(BASESURF, BLANKCOLOR, (moveLeft, moveTop, BLOCKSIZE, BLOCKSIZE))
    # 连续绘制被移动的方块
    # print(animationSpeed)  # 26 方块移动速度
    for i in range(0, BLOCKSIZE, 1):
        checkForQuit()
        WINSET.blit(BASESURF, (0, 0))
        if direction == UP:
            drawTile(movex, movey, board[movex][movey], 0, -i)
        if direction == DOWN:
            drawTile(movex, movey, board[movex][movey], 0, i)
        if direction == LEFT:
            drawTile(movex, movey, board[movex][movey], -i, 0)
        if direction == RIGHT:
            drawTile(movex, movey, board[movex][movey], i, 0)
        pygame.display.update()  # 更新界面
        FPSCLOCK.tick(FPS)  # 控制帧率
# 判断无效移动
def isValidMove(board, direction):
    blankx, blanky = getBlankPosition(board)
    if blankx == 1 and direction == DOWN:
        return False
    elif blankx == 3 and direction == UP:
        return False
    elif blanky == 1 and direction == RIGHT:
        return False
    elif blanky == 3 and direction == LEFT:
        return False
    else:
        return True
# 获取随机移动的方向
def getRandomMove(board, lastMove=None):
    validMoves = [UP, DOWN, LEFT, RIGHT]
    if lastMove == UP or not isValidMove(board, DOWN):
        validMoves.remove(DOWN)
    if lastMove == DOWN or not isValidMove(board, UP):
        validMoves.remove(UP)
    if lastMove == LEFT or not isValidMove(board, RIGHT):
        validMoves.remove(RIGHT)
    if lastMove == RIGHT or not isValidMove(board, LEFT):
        validMoves.remove(LEFT)
    return random.choice(validMoves)
def getBlankPosition(board):
    for x in range(COL):
        for y in range(ROW):
            if board[x][y] == BLANK:
                return (x, y)
def getSpotClicked(board, x, y):
    for tilex in range(len(board)):
        for tiley in range(len(board[0])):
            left, top = getLeftTopOfTile(tilex, tiley)
            tileRect = pygame.Rect(left, top, BLOCKSIZE, BLOCKSIZE)
            if tileRect.collidepoint(x, y):  # 如果产生碰撞
                return tilex, tiley  # 返回行列
    return None, None
# 获取用户输入
def getInput(mainBoard):
    events = pygame.event.get()
    userInput = None
    for event in events:
        if event.type == MOUSEBUTTONUP:
            # 获取位置关系
            spotx, spoty = getSpotClicked(mainBoard, event.pos[0], event.pos[1])
            # 坐标不在拼图区域,点击的新游戏
            if (spotx, spoty) == (None, None) and NEW_RECT.collidepoint(event.pos):
                userInput = NEWGAME
            else:
                # 如果已完成,点击非选项时不移动
                if mainBoard == getStartingBoard():
                    break
                # 点击位置是否在BLANK旁边
                blankx, blanky = getBlankPosition(mainBoard)
                if spotx == blankx + 1 and spoty == blanky:
                    userInput = LEFT  # 设置移动方向
                elif spotx == blankx - 1 and spoty == blanky:
                    userInput = RIGHT
                elif spotx == blankx and spoty == blanky + 1:
                    userInput = UP
                elif spotx == blankx and spoty == blanky - 1:
                    userInput = DOWN
    return userInput
# 对用户输入进行处理
def processing(userInput, mainBoard, msg):
    if mainBoard == getStartingBoard():
        msg = '完成'
    else:
        msg = '通过鼠标移动方块'
    if userInput:
        # 功能按钮
        if userInput == NEWGAME:
            initBoard = getStartingBoard()
            mainBoard = generateNewPuzzle(AUTOMOVE)
            drawBoard(initBoard, msg)  # 动态界面绘制
        else:
            # 方块移动
            slideAnimation(mainBoard, userInput, msg, 8)
            makeMove(mainBoard, userInput)
    return mainBoard, msg
# 资源回收与程序退出
def terminate():
    pygame.quit()  # 模块卸载
    sys.exit()
# 退出判断
def checkForQuit():
    for event in pygame.event.get(QUIT):  # 获取所有可能会导致退出的事件,存在就执行退出
        terminate()  # 执行退出
    for event in pygame.event.get(KEYUP):  # 按下ESC键退出
        if event.key == K_ESCAPE:
            terminate()
        pygame.event.post(event)  # 发送事件至消息列队
def main():
    # FPSCLOCK Clock对象
    # WINSET 窗体Surface对象
    # STATICSURF 静态窗体Surface对象
    # BASICFONT 字体对象
    # NEW_SURF "新游戏"Surface对象,一张内容为文字的图片  调用字体对象的render()方法,渲染为Surface对象显示
    # NEW_RECT get_rect()方法获取的"新游戏"矩形属性
    global FPSCLOCK, WINSET, STATICSURF, BASICFONT  # 定义全局变量
    global NEW_SURF, NEW_RECT
    pygame.init()
    FPSCLOCK = pygame.time.Clock()  # 创建一个Clock对象,并使用变量FPSCLOCK保存
    BASICFONT = pygame.font.Font('STKAITI.TTF', 25)  # 定义返回一个字体对象,并使用变量BASICFONT保存
    WINSET, NEW_SURF, NEW_RECT = darwStaticWin()  # 创建静态窗口
    STATICSURF = WINSET.copy()  # 复制一个静态窗口作为底板
    mainBoard = generateNewPuzzle(AUTOMOVE)  # 初始化列表
    msg = None
    while True:
        FPSCLOCK.tick(FPS)  # 设置帧率
        drawBoard(mainBoard, msg)  # 动态界面绘制
        pygame.display.update()  # 刷新
        checkForQuit()  # 判断是否终止
        userInput = getInput(mainBoard)  # 获取输入
        mainBoard, msg = processing(userInput, mainBoard, msg)  # 输入处理
if __name__ == '__main__':
    main()


Python笔记相关(下):https://developer.aliyun.com/article/1488579

相关文章
|
4天前
|
存储 设计模式 算法
|
4天前
|
Python
小笔记:Python 使用字符串调用函数
小笔记:Python 使用字符串调用函数
45 0
|
4天前
|
JavaScript 前端开发 测试技术
[小笔记]TypeScript/JavaScript模拟Python中的Range函数
[小笔记]TypeScript/JavaScript模拟Python中的Range函数
31 0
|
4天前
|
数据采集 数据可视化 数据挖掘
【新手解答】Python中Pandas的初学者笔记
【新手解答】Python中Pandas的初学者笔记
6 0
|
4天前
|
Java 开发者 索引
Python基础语法:类笔记
本篇博文是把自己在学习python类的过程中自己理解和笔记,一点一点总结的写出出来,做一个总结,加深对面向对象编程的理解。
|
4天前
|
Python
【Python笔记】pip intall -e命令:让你的工程直接使用开源包的源码,可断点调试,修改源码!
【Python笔记】pip intall -e命令:让你的工程直接使用开源包的源码,可断点调试,修改源码!
20 0
|
4天前
|
存储 索引 Python
|
4天前
|
JavaScript 前端开发 测试技术
[小笔记]TypeScript/JavaScript模拟Python中的zip(不使用map)
[小笔记]TypeScript/JavaScript模拟Python中的zip(不使用map)
20 0
|
4天前
|
C# Python
C# 笔记3 - 重载一系列像python那样的print()方法
C# 笔记3 - 重载一系列像python那样的print()方法
30 1
|
4天前
|
关系型数据库 MySQL 数据库
MySQL命令笔记+Python案例
MySQL命令笔记+Python案例
47 0