1. 程式人生 > >python之4個小作業

python之4個小作業

set 進行 顯示 imp 位置 new 出現 primary 數值

第一道小題
"""

1.雙人版2048遊戲

"""

import random,itertools,pygame,sys
pygame.init()
screencaption=pygame.display.set_caption(‘2048小遊戲‘)
screen=pygame.display.set_mode([1320,900])
screen.fill([230,230,230])

class Gamefield:
    def __init__(self,win_value=2048):
        self.win_value = win_value
        self.best_score1 = 0
        self.score1 = 0
        self.best_score2 = 0
        self.score2 = 0

    #畫圖形界面(此函數值負責構建圖形界面窗口,沒有將值繪畫在界面上)
    def init_screen(self):
        screen.fill([230, 230, 230])
        for i in range(4):
            for j in range(8):
                left = 150 * j + 10 * j + 15
                top = 150 * i + 10 * i + 110
                if j > 3:
                    left += 20
                pygame.draw.rect(screen, [120, 120, 120], [left, top, 150, 150], 0) #畫長寬都是150的方塊
        self.draw_number(‘歷史最高:‘+str(self.best_score1),330,25,30,(0,120,120))
        self.draw_number(‘當前分數:‘ + str(self.score1), 330, 60, 30, (0, 120, 120))
        self.draw_number(‘歷史最高:‘ + str(self.best_score2), 990, 25, 30, (0, 120, 120))
        self.draw_number(‘當前分數:‘ + str(self.score2), 990, 60, 30, (0, 120, 120))
        game.draw_number(‘移動:上(w) 下(s) 左(a) 右(d) 重置(r)‘, 330, 780, 30, (0, 0, 0))
        game.draw_number(‘移動:上(↑) 下(↓) 左(←) 右(→) 重置(r)‘, 990, 780, 30, (0, 0, 0))
        pygame.draw.line(screen, (120,120,120), [0, 100], [1320, 100], 5)
        pygame.draw.line(screen, (120, 120, 120), [0, 750], [1320, 750], 5)
        pygame.draw.line(screen, (120, 120, 120), [2.5, 100], [2.5, 750], 5)
        pygame.draw.line(screen, (120, 120, 120), [660, 100], [660, 750], 5)
        pygame.draw.line(screen, (120, 120, 120), [1317.5, 100], [1317.5, 750], 5)

    #把字符數字畫到界面對應位置
    def draw_number(self,str,left,top,font=60,color=(0, 0, 128)):
        # 創建一個Font對象
        fontObj = pygame.font.SysFont(‘arplukaitwmbe‘, font)

        # fontObj.render(字符串,True或False(指定是否要抗鋸齒),字體顏色,[背景底色])的返回一個Surface對象
        textSurfaceObj = fontObj.render(str, True, color)

        # Surface對象的get_rect()方法,從Surface對象創建一個Rect對象,這個Rect對象可以計算出文本的正確坐標
        textRectObj = textSurfaceObj.get_rect()

        # 將Rect對象的中心設置為(left,top)
        textRectObj.center = (left,top)

        # 在屏幕繪制文本
        screen.blit(textSurfaceObj, textRectObj)

    #每次移動後,重畫界面
    def init_ui(self,flag,li1,li2):
        self.init_screen()  #調用函數畫圖形界面
        if flag == 1:
            if ‘ ‘ in list(itertools.chain(*game_list1)):    #flag = 1表示第一個列表移動,如果列表還有空位置,則新產生一個數,沒有則不產生
                self.create_num1()
        if flag == 2:
            if ‘ ‘ in list(itertools.chain(*game_list2)):    #flag = 2表示第二個列表移動,如果列表還有空位置,則新產生一個數,沒有則不產生
                self.create_num2()
            # 把列表裏的數值畫進圖形界面裏
        for i in range(4):
            for j in range(4):
                left = 90 + 160 * j
                top = 195 + 160 * i
                self.draw_number(str(li1[i][j]), left, top)  # 畫列表1裏面的值
                self.draw_number(str(li2[i][j]), left + 660, top)  # 畫列表2裏面的值

    # 給空列表裏產生兩個初始值,並畫到界面
    def reset(self):
        if self.score1 > self.best_score1:
            self.best_score1 = self.score1
        if self.score2 > self.best_score2:
            self.best_score2 = self.score2
        self.score1 = 0
        self.score2 = 0
        for i in range(2):
            self.create_num1()
            self.create_num2()
        self.init_ui(0, game_list1, game_list2)     #遊戲初始化的時候,沒有移動列表,因此設flag為0,就不用產生新的數值了

    # 1移動一次就出現一個新的數字,game_list1
    def create_num1(self):
        while True:
            i = random.randint(0, 3)
            j = random.randint(0, 3)
            if game_list1[i][j] == ‘ ‘:
                game_list1[i][j] = random.choice([2, 2, 2, 4])
                break
            else:
                continue

    # 2移動一次就出現一個新的數字,game_list2
    def create_num2(self):
        while True:
            i = random.randint(0, 3)
            j = random.randint(0, 3)
            if game_list2[i][j] == ‘ ‘:
                game_list2[i][j] = random.choice([2, 2, 2, 4])
                break
            else:
                continue

    # 矩陣反轉
    def invert(self,li):
        return [i[::-1] for i in li]

    # 矩陣轉置
    def transpose(self,li):
        return [list(i) for i in zip(*li)]

    # 判斷能否左移,右移,上移,下移
    def is_moving_left(self,li):
        for i in range(4):
            for j in range(3):
                if li[i][j] == ‘ ‘ and li[i][j + 1] != ‘ ‘:
                    return True
                else:
                    if li[i][j] != ‘ ‘ and li[i][j] == li[i][j + 1]:
                        return True
        else:
            return False
    def is_moving_right(self,li):
        li = self.invert(li)
        return self.is_moving_left(li)
    def is_moving_up(self,li):
        li = self.transpose(li)
        return self.is_moving_left(li)
    def is_moving_down(self,li):
        li = self.transpose(li)
        li = self.invert(li)
        return self.is_moving_left(li)

    # 進行左移,右移,上移,下移,flag的值表示移動的是第1個或第2個數值列表
    def move_left(self,flag,li):
        new_li = []
        for row in li:
            row_list = sorted(row, key=lambda x: 1 if x == ‘ ‘ else 0)
            self.add_number(flag,row_list)
            new_li.append(row_list)
        return new_li
    def move_right(self,flag,li):
        li = self.invert(li)
        li = self.move_left(flag,li)
        li = self.invert(li)
        return li
    def move_up(self,flag,li):
        li = self.transpose(li)
        li = self.move_left(flag,li)
        li = self.transpose(li)
        return li
    def move_down(self,flag,li):
        li = self.transpose(li)
        li = self.invert(li)
        li = self.move_left(flag,li)
        li = self.transpose(li)
        return li[::-1]

    #移動之後消數字:在移動方向上把兩個相等的數字加起來
    def add_number(self,flag,row):
        for j in range(3):
            if row[j] != ‘ ‘ and row[j] == row[j + 1]:
                row[j] *= 2
                if flag == 1:
                    self.score1 += row[j]
                else:
                    self.score2 += row[j]
                row[j + 1] = ‘ ‘

    #判斷是否有數值達到2048
    def is_get_2048(self,li):
        li = list(itertools.chain(*li))
        if max([i for i in li if i != ‘ ‘]) >= 2048:
            return True
        else:
            return False
    #判斷是否能繼續移動
    def is_move(self,li):
        return any((self.is_moving_left(li), self.is_moving_right(li), self.is_moving_up(li), self.is_moving_down(li)))

#遊戲開始
game_list1 = []  #存放數字的空列表
game_list2 = []  #存放數字的空列表
[game_list1.append([‘ ‘ for j in range(4)]) for i in range(4)]   #利用列表生成式生成空列表(二維數組)
[game_list2.append([‘ ‘ for j in range(4)]) for i in range(4)]
game = Gamefield()  #創建遊戲類的實例
game.reset()

while True:

    if game.is_move(game_list1) or game.is_move(game_list2):
        if not game.is_move(game_list1) and not game.is_get_2048(game_list1):
            game.draw_number(‘笨蛋,遊戲失敗!‘, 330, 850, 30, (255, 0, 0))
        elif not game.is_move(game_list1) and game.is_get_2048(game_list1):
            game.draw_number(‘恭喜你!其實你已經得到了2048!‘, 330, 850, 30, (255, 0, 0))
        elif game.is_move(game_list1) and game.is_get_2048(game_list1):
            game.draw_number(‘2048分已到手!繼續創高分!‘, 330, 850, 30, (255, 0, 0))
        if not game.is_move(game_list2) and not game.is_get_2048(game_list2):
            game.draw_number(‘笨蛋,遊戲失敗!‘, 990, 850, 30, (255, 0, 0))
        elif not game.is_move(game_list2) and game.is_get_2048(game_list2):
            game.draw_number(‘恭喜你!其實你已經得到了2048!‘, 990, 850, 30, (255, 0, 0))
        elif game.is_move(game_list2) and game.is_get_2048(game_list2):
            game.draw_number(‘2048分已到手!繼續創高分!‘, 990, 850, 30, (255, 0, 0))
    else:
        if game.is_get_2048(game_list1):
            game.draw_number(‘恭喜你!其實你已經得到了2048!‘, 330, 850, 30, (255, 0, 0))
        else:
            game.draw_number(‘笨蛋,遊戲失敗!‘, 330, 850, 30, (255, 0, 0))
        if game.is_get_2048(game_list2):
            game.draw_number(‘恭喜你!其實你已經得到了2048!‘, 990, 850, 30, (255, 0, 0))
        else:
            game.draw_number(‘笨蛋,遊戲失敗!‘, 990, 850, 30, (255, 0, 0))

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_r:
                game.draw_number(‘重置!遊戲重新開始!‘, 330, 850, 30, (255, 0, 0))
                game_list1 = []
                game_list2 = []
                [game_list1.append([‘ ‘ for j in range(4)]) for i in range(4)]
                [game_list2.append([‘ ‘ for j in range(4)]) for i in range(4)]
                game.reset()
            elif event.key == pygame.K_LEFT:
                while game.is_moving_left(game_list2):
                    game_list2 = game.move_left(2,game_list2)
                game.init_ui(2,game_list1,game_list2)
            elif event.key == pygame.K_RIGHT:
                while game.is_moving_right(game_list2):
                    game_list2 = game.move_right(2,game_list2)
                game.init_ui(2,game_list1,game_list2)
            elif event.key == pygame.K_UP:
                while game.is_moving_up(game_list2):
                    game_list2 = game.move_up(2,game_list2)
                game.init_ui(2,game_list1,game_list2)
            elif event.key == pygame.K_DOWN:
                while game.is_moving_down(game_list2):
                    game_list2 = game.move_down(2,game_list2)
                game.init_ui(2,game_list1,game_list2)
            elif event.key == pygame.K_a:
                while game.is_moving_left(game_list1):
                    game_list1 = game.move_left(1,game_list1)
                game.init_ui(1,game_list1,game_list2)
            elif event.key == pygame.K_d:
                while game.is_moving_right(game_list1):
                    game_list1 = game.move_right(1,game_list1)
                game.init_ui(1,game_list1,game_list2)
            elif event.key == pygame.K_w:
                while game.is_moving_up(game_list1):
                    game_list1 = game.move_up(1,game_list1)
                game.init_ui(1,game_list1,game_list2)
            elif event.key == pygame.K_s:
                while game.is_moving_down(game_list1):
                    game_list1 = game.move_down(1,game_list1)
                game.init_ui(1,game_list1,game_list2)
    pygame.display.update()

遊戲截圖
技術分享圖片

技術分享圖片

技術分享圖片

第二道小題

"""
2. 文件score.dat中保存的是100名學生的姓名和Python課、高數和英語成績。

(1)定義學生類,其中包含姓名、Python課、高數和英語成績及總分、均分數據成員,成員函數根據需要確定。
(2)讀入這名學生的成績,用對象列表進行存儲。
(3)求出各科和總分的最高分。
(4)請按總分的降序(高成績在前,低成績在後)排序
(5)在屏幕上顯示各科及總分的最高分,排序後的成績單(包括總分)保存到文件odered_score.dat中。
(6) 將文件中的所有學生信息, 保存在mariadb數據庫中;
"""
import random
import pymysql as mysql

u = ‘root‘
p = ‘westos‘
d = ‘python‘

class Student:
    def __init__(self, name, py_score, gs_score, eng_score):
        self.name = name
        self.py_score = py_score
        self.gs_score = gs_score
        self.eng_score = eng_score
        self.score = self.py_score + self.gs_score + self.eng_score
        self.average = self.score / 3

def create_stu(i):
    name = ‘stu‘ + str(i+1)
    score1 = str(random.randint(40, 100))
    score2 = str(random.randint(40, 100))
    score3 = str(random.randint(40, 100))
    return name, score1, score2, score3

with open(‘score.dat‘, ‘w‘) as f:
    for i in range(100):
        s = create_stu(i)
        f.write(s[0]+‘ ‘+s[1]+‘ ‘+s[2]+‘ ‘+s[3]+‘\n‘)

data_list = []
student_list = []
with open(‘score.dat‘, ‘r‘) as f:
    py_score_list = []
    gs_score_list = []
    eng_score_list = []
    score_list = []
    i = 0
    while True:
        line = f.readline().strip()
        if not line:
            break
        else:
            i += 1
            name, score1, score2, score3 = line.split()
            stu = Student(name, int(score1),int(score2), int(score3))
            data_list.append((i, name, stu.py_score, stu.gs_score, stu.eng_score, stu.score))
            student_list.append(stu)
            py_score_list.append(stu.py_score)
            gs_score_list.append(stu.gs_score)
            eng_score_list.append(stu.eng_score)
            score_list.append(stu.score)
    print(‘Python最高分:‘, max(py_score_list))
    print(‘高數最高分:‘, max(gs_score_list))
    print(‘英語最高分:‘, max(eng_score_list))
    print(‘總分最高分:‘, max(score_list))
    student_list = sorted(student_list, key=lambda stu : stu.score, reverse=True)

with open(‘odered_score.dat‘,‘w‘) as f:
    for stu in student_list:
        f.write(stu.name+‘ ‘+str(stu.py_score)+‘ ‘+str(stu.gs_score)+‘ ‘+str(stu.eng_score)+‘ ‘+str(stu.score)+‘\n‘)

conn = mysql.connect(user=u,passwd=p,db=d,charset=‘utf8‘,autocommit=True)
cur = conn.cursor()
try:
    cur.execute(‘create table student(id int primary key,name varchar(20),python int,gaoshu int,english int,sum_score int);‘)
except Exception as e:
    print(‘創建成績表出現錯誤...‘, ‘\n‘, e)
else:
    print(‘在數據庫創建成績表成功....‘)
try:
    cur.executemany(‘insert into student values(%s,%s,%s,%s,%s,%s);‘, data_list)
except Exception as e:
    print(‘數據庫插入數據出現錯誤...‘, ‘\n‘, e)
else:
    print(‘成績錄入數據庫成功......‘)
cur.close()
conn.close()

運行截圖
技術分享圖片

技術分享圖片

第三道小題

"""
3. 知識點復習
正整數A和正整數B 的最小公倍數是指 能被A和B整除的最小的正整數值,設計一個算法,求輸入A和B的最小公倍數。
- 輸入描述: 輸入兩個正整數A和B。
- 輸出描述: 輸出A和B的最小公倍數。
"""

def gas(m,n):
    return m if n ==  0 else gas(n,m%n)
m,n = input(‘輸入整數A,B:‘).split()
print(int(int(m)*int(n)/gas(int(m),int(n))))

運行截圖
技術分享圖片

第四道小題

"""
4. 題目描述
Catcher 是MCA國的情報員,他工作時發現敵國會用一些對稱的密碼進行通信,比如像這些ABBA,ABA,A,123321,但是他們有時會在開始或結束時加入一些無關的字符以防止別國破解。比如進行下列變化 ABBA->12ABBA,ABA->ABAKK,123321->51233214 。因為截獲的串太長了,而且存在多種可能的情況(abaaab可看作是aba,或baaab的加密形式),Cathcer的工作量實在是太大了,他只能向電腦高手求助,你能幫Catcher找出最長的有效密碼串嗎?
(註意:記得加上while處理多個測試用例)
- 輸入描述:輸入一個字符串
- 輸出描述:返回有效密碼串的最大長度

"""
ps:我將解密後的密碼也打印出來了。

s = input(‘輸入加密字符串:‘)

while s != ‘q‘:
    tmp = s
    li = []
    max = 0
    for i in range(len(s)):
        tmp = s[i:]
        if tmp != tmp[::-1]:
            for j in range(1,len(s)):
                tmp = s[i:-j]
                if tmp != tmp[::-1]:
                    continue
                else:
                    if max == len(tmp):
                        li.append(tmp)
                    elif max < len(tmp):
                        max = len(tmp)
                        li = [tmp]
                        break
                    else:
                        break
        else:
            if max == len(tmp):
                li.append(tmp)
            elif max < len(tmp):
                max = len(tmp)
                li = [tmp]
                break
            else:
                break
    print(‘最長有效密碼串長度:‘,max,‘最長有效密碼串列表:‘,li)
    s = input(‘輸入加密字符串,或者按q退出:‘)

運行截圖
技術分享圖片

python之4個小作業