吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3090|回复: 26
收起左侧

[Python 转载] PYTHON版贪吃蛇

[复制链接]
c03xp 发表于 2020-9-3 12:57
本帖最后由 c03xp 于 2020-9-7 12:50 编辑

我看别人发的小游戏挺有意思,自己也跃跃欲试,写了个PYTHON版贪吃蛇。原创亮点是调用win32函数随意移动光标位置,并且隐藏光标的显示。
理论上还可以继续优化,减小抖动,那样的话代码量可能会大一点。

已更新为彩色版

[Python] 纯文本查看 复制代码
#!/usr/bin/python
# -*- coding: UTF-8 -*-
import threading, os, msvcrt, ctypes, time, sys, random, math, copy


class COORD(ctypes.Structure):
    _fields_ = [("X",ctypes.c_short),("Y",ctypes.c_short)]
	
class CURSOR_INFO(ctypes.Structure):
    _fields_ = [("dwSize",ctypes.c_uint),("bVisible",ctypes.c_uint)]
    

ww = 9          #列数
wh = 16         #行数
interval = 0.15  #帧间隔
invincible = False  #无敌模式:off

xboundary = 2
yboundary = 2
title = "\u3000"*int( (ww + xboundary/2 - 3)/2) + "贪吃蛇\n"
ceiling = "\u3000" + "▁"*ww + "\u3000\n"
floor = "\u3000" + "▔"*ww + "\u3000\n"
middle = ("▕"+"\u3000"*ww + "▏\n")*wh
bkground = title + ceiling + middle + floor + "\u3000"*30   #背景数据,最后是信息提示区
nexts = {b"d":1,b"a":-1,b"s":ww,b"w":-ww}  #按键-蛇头位移 映射表
snake = food = nx = None
foods = []
for i in range(ww*wh):
    foods.append(i)

def writeCh(idx,ch,color=7):   
    '''写入一个字符。写屏范围是一个矩形空间,可用一维坐标idx或二维坐标x,y定位'''
    if(0 <= idx < ww*wh):
        dll.SetConsoleCursorPosition(hStdOut,COORD( (idx % ww)*2 + xboundary,int( idx / ww ) + yboundary))    #定位光标时,将矩形空间坐标转换成命令行坐标
        dll.SetConsoleTextAttribute(hStdOut,color)
        print(ch,end="")
        sys.stdout.flush()
        dll.SetConsoleTextAttribute(hStdOut,7)
def clearScreen():    
    '''清除内容并重画背景'''
    dll.SetConsoleCursorPosition(hStdOut,COORD(0,0))
    print(bkground)
def gameInit():         
    '''初始化游戏数据'''
    global snake,food,nx
    clearScreen()
    snake = [int(wh/2)*ww]
    food = list(set(foods) - set(snake))[random.randint(0,len(list(set(foods) - set(snake)))-1)]
    nx = nexts[b"d"] 
    while(msvcrt.kbhit()):	#清空缓冲区
        msvcrt.getch()	
def collision():       
    '''碰撞检测'''
    if(snake[0] < 0 or snake[0] >= ww*wh):      #上下出界
        return not invincible
    if(nx == 1 and snake[0]%ww == 0):           #撞右墙
        return not invincible
    if(nx == -1 and (snake[0] + 1)%ww == 0):    #撞左墙
        return not invincible
    if(snake[0] in snake[1:]):                  #撞蛇身
        return not invincible
    return False
def run():              
    '''主循环'''
    global snake,food,nx
    '''计算当前帧'''    
    if(msvcrt.kbhit()):
        while(msvcrt.kbhit()):	#获取按键输入
            ch = msvcrt.getch()
        if(ch in nexts.keys()):
            #if(nx + nexts[ch] != 0 or len(snake) < 2): #注释掉这条限制是为了无敌模式时畅行无阻
            nx = nexts[ch]  #按键输入映射到蛇头位移
    snake.insert(0,snake[0] + nx)
    if(snake[0] == food):
        food = list(set(foods) - set(snake))[random.randint(0,len(list(set(foods) - set(snake)))-1)]
    else:
        snake.pop()       
    '''绘制当前帧'''
    if(collision()):
        dll.SetConsoleCursorPosition(hStdOut,COORD(0,wh + 3))
        print("Game Over")
        time.sleep(2)
        gameInit()
    clearScreen()    
    for el in snake[1:]:     #绘制蛇身
        writeCh(el,"\u25a0",12)
    writeCh(snake[0],"◆",12)   #绘制蛇头
    writeCh(food,"\u2605",10)   #绘制食物   
    threading.Timer(interval,run).start() 
    
'''''''''''''''''主程序'''''''''''''''''''''
dll = ctypes.WinDLL("Kernel32.dll")
hStdOut = dll.GetStdHandle(-11)		#GetStdHandle(STD_OUTPUT_HANDLE)
dll.SetConsoleCursorPosition.argtypes = [ctypes.c_int,COORD]
dll.SetConsoleCursorInfo.argtypes = [ctypes.c_int,ctypes.c_void_p]
ci = CURSOR_INFO(1,0)
dll.SetConsoleCursorInfo(hStdOut,id(ci))

os.system("cls")
gameInit()
run()




snake6.png

免费评分

参与人数 1吾爱币 +7 热心值 +1 收起 理由
苏紫方璇 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| c03xp 发表于 2020-9-3 17:23
涛之雨 发表于 2020-9-3 17:11
就是贪吃蛇向右移动的时候按左键应该是没有效果的,
而这个会直接死亡。
应该是少了一个判断吧?

明白了,多谢提醒,可以这样改一下:

[Python] 纯文本查看 复制代码
        if(ch in nexts.keys()):
            if(nx + nexts[ch] != 0 or len(snake) < 2):
                nx = nexts[ch]  #按键输入映射到蛇头位移
涛之雨 发表于 2020-9-3 16:53
运行了一下,挺好的,
有个bug(算是吧)
image.png
这种不可能存在的情况也会出现
(向右走的时候按左键,其他同理)

此外可以用
[Python] 纯文本查看 复制代码
os.system("mode con:cols=23 lines=22") 

设置窗口大小
image.png
当然主要是前来学习算法(哈哈哈哈哈)
nmgnclxd 发表于 2020-9-3 13:15
落雨碎江南 发表于 2020-9-3 13:16
厉害了楼主
辰迷星海 发表于 2020-9-3 13:16
感谢分享
弗由 发表于 2020-9-3 13:21
这个好,感谢分享。
guide 发表于 2020-9-3 13:24
感谢分享
小木剑 发表于 2020-9-3 13:45
哈哈,很厉害
刀大喵 发表于 2020-9-3 13:48
贪吃蛇 编程学习常遇到的例子
fengling375 发表于 2020-9-3 13:51
100行,厉害
xm3834 发表于 2020-9-3 14:00
感谢你的分享支持一下
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-26 01:33

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表