zoukankan      html  css  js  c++  java
  • Mini projects #5 ---- Memory

    课程全名:An Introduction to Interactive Programming in Python,来自 Rice University

    授课教授:Joe Warren, Scott Rixner, John Greiner, Stephen Wong

    工具:http://www.codeskulptor.org/, simplegui 模块

     

    第5周讲述

    1. simplegui模块中鼠标的控制方式

    2. list的各种操作, append, pop, extend, index, remove, reverse, sort

    3. Iteration,迭代器,遍历对象方式 for x in lst:… 或者列表生成式 [exp for x in lst]

    [exp for x in lst] # 迭代器,遍历x中的所有元素x执行exp的操作,返回一个计算完整的列表

    (exp for x in lst) # 生成器,也是一种迭代器,返回一个迭代对象,不计算所有结果,只提供当前需要访问的next元素,所以生成器只能迭代一次。好处是节省内存

    4. dictionaries, python中的字典dict, {},键值对

    字典中只有immutable对象可以做key,value可以是任意的

    例如:d = {(1,2):[1,2,3], True:{1:2}, "123":(1,2), 4:5}

    immutable 对象: string, int, float, tuple, bool,(值类型)

    mutable 对象: list, dictionary, set,(自定义类型,引用类型)

    其他的就是浅拷贝和深拷贝的问题:

    当进行a=b赋值操作,如果是immutable对象,a作为b的一个拷贝创建,a和b独立。如果是mutable对象,a作为b的一个引用创建,a和b共享。

    浅拷贝---构造一个新的复合对象,使用原来对象元素的引用,(对于immutable类型相当于拷贝)填充新对象。

    深拷贝---构造一个新的复合对象,同时递归拷贝对象所包含的所有元素。

    copy模块中

    copy.copy(x) # return a shallow copy of x

    copy.deepcopy(x) # return a deep copy of x

     

    5. simplegui模块中图像的载入,load_image

     

    本周的游戏:

    完成一个数字记忆相关游戏,界面如下

    image

    游戏的规则:

    1. 共有16个数字,他们是成对的0-7共8组,随机分布在16个格子里。

    2. 初始都是cover状态,通过鼠标点击卡牌可以uncover查看对应的数字。

    3. 如果连续两次点击为相同数字,那么数字会保留uncover状态。

    4. 如果连续两次的点击为不相同数字,当点击第三个数字,原先卡牌uncover状态将恢复成cover

    5. Turns记录每轮点击次数,并且重复点击已经点开的卡牌没有效果,reset重置游戏。

    游戏框架:

    def new_game() # 游戏初始化

    1. 思考关于游戏逻辑,需要记录那些属性,至少有个list用来记录16个数字,命名为memory_list好了。还要有个list记录哪些牌需要翻开哪些牌是不翻开的,命名为exposed。需要初始化turns,turns为一个数值记录当前次数。需要一个list命名prev_card_id用来记录先前翻开的牌。还需要state变量,记录当前处于游戏的哪个状态,0表示处于初始状态,1表示已经翻开一张牌

    2. 初始化memory_list,直接生成0-16然后对8取模,在进行shuffle

    memory_list = [i%8 for i in range(16)]
    random.shuffle(memory_list)

     

    def mouseclick(pos) # 鼠标交互事件

    1. 鼠标点击,得到了什么?鼠标点击的坐标位置,那需要什么?点了哪张牌。so,for循环枚举每张牌的左右两条竖线(x方向信息),判断点击牌序号存在card_id

    2. 如果当前牌是uncover,或者点击极限位置没找到牌(可能么?)的那么就不管他,否则,进入游戏规则2、3、4的逻辑判断。

    需要注意就是,在状态0时候,要先把prev_card_id里面的卡牌状态翻转成未翻开

    if state == 0:
        for i in prev_card_id:
            exposed[i] = False
        prev_card_id = [card_id]
        exposed[card_id] = True
        turns += 1
        state = 1
        label.set_text("Turns = " + str(turns))
    else:
        exposed[card_id] = True
        state = 0
        if memory_list[prev_card_id[0]] == memory_list[card_id]:
            exposed[card_id] = True
            prev_card_id = []
        else: 
            prev_card_id.append(card_id)

    def draw(canvas) # 界面绘制事件

    界面就负责绘制,800的宽度分成16份

    第i个的宽度分别是i*50, (i+1)*50

    1.如果exposed[i]是True,翻开就绘制Text

    2.否则,未翻开就绘制polygon

    for i in range(len(exposed)):
        if exposed[i]:
            canvas.draw_text(str(memory_list[i]), (i*50+10, 100/1.75), 50, 'White')
        else:
            canvas.draw_polygon([(i*50, 0), ((i+1)*50, 0), ((i+1)*50, 100), ((i*50), 100)], 1, 'Red', 'Green')

    完整代码如下:

    # implementation of card game - Memory
    
    import simplegui
    import random
    
    # helper function to initialize globals
    def new_game():
        global exposed, prev_card_id, turns, memory_list, state
        # init variables
        exposed = [False]*16
        turns = state = 0
        label.set_text("Turns = " + str(turns))
        prev_card_id = []
        memory_list = [i%8 for i in range(16)]
        random.shuffle(memory_list)
        
    # define event handlers
    def mouseclick(pos):
        global state, prev_card_id, exposed, turns
        # find the clicked card's id
        card_id = -1
        for i in range(len(exposed)):
            if pos[0] >= i*50 and pos[0] < (i+1)*50:
                card_id = i
    
        if (card_id != -1) and (exposed[card_id] is False):
            # state logic processed
            if state == 0:
                for i in prev_card_id:
                    exposed[i] = False
                prev_card_id = [card_id]
                exposed[card_id] = True
                turns += 1
                state = 1
                label.set_text("Turns = " + str(turns))
            else:
                exposed[card_id] = True
                state = 0
                if memory_list[prev_card_id[0]] == memory_list[card_id]:
                    exposed[card_id] = True
                    prev_card_id = []
                else: 
                    prev_card_id.append(card_id)
                            
    # cards are logically 50x100 pixels in size   
    def draw(canvas):    
        for i in range(len(exposed)):
            if exposed[i]:
                canvas.draw_text(str(memory_list[i]), (i*50+10, 100/1.75), 50, 'White')
            else:
                canvas.draw_polygon([(i*50, 0), ((i+1)*50, 0), ((i+1)*50, 100), ((i*50), 100)], 1, 'Red', 'Green')
    
    # create frame and add a button and labels
    frame = simplegui.create_frame("Memory", 800, 100)
    frame.add_button("Reset", new_game, 200)
    label = frame.add_label("Turns = 0")
    
    # register event handlers
    frame.set_mouseclick_handler(mouseclick)
    frame.set_draw_handler(draw)
    
    # get things rolling
    new_game()
    frame.start()
    
    
    # Always remember to review the grading rubric
  • 相关阅读:
    Value '0000-00-00' can not be represented as java.sql.Date
    mysql建表设置两个默认CURRENT_TIMESTAMP的技巧
    PowerDesigner 的mysql PDM 的COMMENT注释
    tomcat配置及优化
    Tomcat7调优及JVM性能优化for Linux环境
    maven混淆Java代码
    通过Maven配置测试环境和开发环境连接不同的数据库
    删除电脑中用强制删除不能删除的bat命令脚本
    在Linux中设置共享目录
    ftp以及smb的配置
  • 原文地址:https://www.cnblogs.com/tiny656/p/4039670.html
Copyright © 2011-2022 走看看