# connect 4_2 --- ## 上次程式碼 ```python= import numpy as np import sys import math ROW=6 COL=7 def create_board(): #創建棋盤 board = np.zeros((ROW, COL)) return board def drop_piece(board, row, col, piece):#把玩家指定的空格填起來 board[row][col] = piece def is_valid_location(board, col):#確認目前還是空的位子 return board[ROW-1][col] == 0 def get_next_open_row(board, col): for r in range(ROW): if board[r][col] == 0: return r def print_board(board):#用來改變陣列方向 print(np.flip(board, axis=0))#flip就是翻轉陣列 def winning_move(board, piece):#判斷是否有人達成獲勝條件 #檢查所有橫線 for c in range(COL-3): for r in range(ROW): if board[r][c] == piece and board[r][c+1] == piece and board[r][c+2] == piece and board[r][c+3] == piece: return True #檢查所有直線 for c in range(COL): for r in range(ROW-3): if board[r][c] == piece and board[r+1][c] == piece and board[r+2][c] == piece and board[r+3][c] == piece: return True #檢查所有斜線 #斜率為正 for c in range(COL-3): for r in range(ROW-3): if board[r][c] == piece and board[r+1][c+1] == piece and board[r+2][c+2] == piece and board[r+3][c+3] == piece: return True board = create_board() print_board(board) turn = 0#用來判斷現在是輪到玩家1還是2 game_over = False while not game_over:#若有玩家贏了用來跳出遊戲 #問玩家1 if turn == 0: col = int(input("玩家1請選一個數字(0 ~ 6)")) if is_valid_location(board, col): row = get_next_open_row(board, col) drop_piece(board, row, col, 1) if winning_move(board,1): print("恭喜玩家1獲勝!!!") game_over=True break #問玩家2 else: col = int(input("玩家2請選一個數字(0 ~ 6)")) if is_valid_location(board, col): row = get_next_open_row(board, col) drop_piece(board, row, col, 2) if winning_move(board,2): print("恭喜玩家2獲勝!!!") game_over=True break print_board(board)#程式有沒有寫錯 turn+=1 turn%=2 ``` --- ## 斜率為負 - 相反的若要判斷斜率為負,則要尋找$(i,j)、(i-1,j+1)、(i-2,j+2)、(i-3,j+3)$這四個點是不是都一樣 ```python= for c in range(COL-3): for r in range(3, ROW): if board[r][c] == piece and board[r-1][c+1] == piece and board[r-2][c+2] == piece and board[r-3][c+3] == piece: return True ``` --- ## 製作成pygame --- ## 引入函式庫 ```python import pygame import numpy as np import sys import math ``` - 在終端機中輸入 pip install pygame --- ## 設定顏色 ```python BLUE = (0, 0, 255)#RGB值 BLACK = (0, 0, 0) RED = (255, 0, 0) YELLOW = (255, 255, 0) ``` --- ## 設定視窗大小 ```python SQUARESIZE = 100#遊戲介面每格的大小 width = COL *SQUARESIZE#遊戲介面的寬 height = (ROW+1) * SQUARESIZE#遊戲介面的長 size = (width, height) ``` --- ## 設定棋子大小 ```python RADIUS = int(SQUARESIZE/2 - 5)#圓的半徑 ``` --- ## 設定視窗大小 ```python screen = pygame.display.set_mode(size) ``` --- ## 設定棋盤和棋子 --- - 要在遊戲視窗中繪製圖形需要用到pygame裡面的draw函式 ```python pygame.draw.形狀(位置, 顏色, (x座標, y座標, 大小)) ``` ```python def draw_board(board): for c in range(COL): for r in range(ROW): pygame.draw.rect(screen, BLUE, (c*SQUARESIZE), (r*SQUARESIZE+SQUARESIZE), SQUARESIZE, SQUARESIZE)#藍色棋盤 pygame.draw.circle(screen, BLACK, (int(c*SQUARESIZE+SQUARESIZE/2), int(r*SQUARESIZE+SQUARESIZE+SQUARESIZE/2)), RADIUS)#黑色空格 ``` ```python for c in range(COL): for r in range(ROW): if board[r][c] == 1: pygame.draw.circle(screen, RED, (int(c*SQUARESIZE+SQUARESIZE/2), height-int(r*SQUARESIZE+SQUARESIZE/2)), RADIUS)#玩家1球的顏色 elif board[r][c] == 2: pygame.draw.circle(screen, YELLOW, (int(c*SQUARESIZE+SQUARESIZE/2), height-int(r*SQUARESIZE+SQUARESIZE/2)), RADIUS)#玩家2球的顏色 pygame.display.update() ``` --- ## 初始化pygame ```python pygame.init() ``` --- ## 顯示視窗 ```python draw_board(board) pygame.display.update() ``` --- ## 設定字體和大小 ```python myfont = pygame.font.SysFont("monospace", 75) ``` --- ## 主要循環 --- ## 製作棋盤和棋子 --- ### 棋盤 ```python for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.MOUSEMOTION: pygame.draw.rect(screen, BLACK, (0, 0, width, SQUARESIZE)) posx = event.pos[0] pygame.display.update() ``` --- ### 棋子 ```python if turn == 0: pygame.draw.circle(screen, RED, (posx, int(SQUARESIZE/2)), RADIUS)#玩家1的棋子 else: pygame.draw.circle(screen, YELLOW, (posx, int(SQUARESIZE/2)), RADIUS)#玩家2的棋子 ``` --- ### 設定滑鼠按下時放置棋子 ```python if event.type == pygame.MOUSEBUTTONDOWN: ``` --- ### 玩家選擇位置 #### 原本 ```python col = int(input("玩家1請選一個數字(0 ~ 6)")) ``` #### 修改後 ```python posx = event.pos[0] col = int(math.floor(posx/SQUARESIZE)) ``` --- ### 獲勝字樣 #### 原本 ```python print("恭喜玩家1獲勝!!!") ``` #### 修改後 ```python label = myfont.render("Player 1 wins!!!", 1, RED) screen.blit(label, (40, 10)) ``` --- ### 更新棋盤 - 每次放完棋子後都要更新一次棋盤和棋子 ```python print_board(board) draw_board(board) ``` --- ### 結束遊戲 ```python if game_over: pygame.time.wait(3000) ``` --- ## 完整程式碼 ```python= import numpy as np import pygame import sys import math BLUE = (0, 0, 255)#RGB值 BLACK = (0, 0, 0) RED = (255, 0, 0) YELLOW = (255, 255, 0) ROW = 6#行數 COL = 7#列數 def create_board(): #創建棋盤 board = np.zeros((ROW, COL)) return board def drop_piece(board, row, col, piece):#把玩家指定的空格填起來 board[row][col] = piece def is_valid_location(board, col):#確認目前還是空的位子 return board[ROW-1][col] == 0 def get_next_open_row(board, col): for r in range(ROW): if board[r][col] == 0: return r def print_board(board):#用來改變陣列方向 print(np.flip(board, axis=0))#flip就是翻轉陣列 def winning_move(board, piece):#判斷是否有人達成獲勝條件 #檢查所有橫線 for c in range(COL-3): for r in range(ROW): if board[r][c] == piece and board[r][c+1] == piece and board[r][c+2] == piece and board[r][c+3] == piece: return True #檢查所有直線 for c in range(COL): for r in range(ROW-3): if board[r][c] == piece and board[r+1][c] == piece and board[r+2][c] == piece and board[r+3][c] == piece: return True #檢查所有斜線 #斜率為正 for c in range(COL-3): for r in range(ROW-3): if board[r][c] == piece and board[r+1][c+1] == piece and board[r+2][c+2] == piece and board[r+3][c+3] == piece: return True #斜率為負 for c in range(COL-3): for r in range(3, ROW): if board[r][c] == piece and board[r-1][c+1] == piece and board[r-2][c+2] == piece and board[r-3][c+3] == piece: return True def draw_board(board): for c in range(COL): for r in range(ROW): pygame.draw.rect(screen, BLUE, (c*SQUARESIZE, r*SQUARESIZE+SQUARESIZE, SQUARESIZE, SQUARESIZE))#藍色棋盤 pygame.draw.circle(screen, BLACK, (int(c*SQUARESIZE+SQUARESIZE/2), int(r*SQUARESIZE+SQUARESIZE+SQUARESIZE/2)), RADIUS)#黑色空格 for c in range(COL): for r in range(ROW): if board[r][c] == 1: pygame.draw.circle(screen, RED, (int(c*SQUARESIZE+SQUARESIZE/2), height-int(r*SQUARESIZE+SQUARESIZE/2)), RADIUS)#玩家1球的顏色 elif board[r][c] == 2: pygame.draw.circle(screen, YELLOW, (int(c*SQUARESIZE+SQUARESIZE/2), height-int(r*SQUARESIZE+SQUARESIZE/2)), RADIUS)#玩家2球的顏色 pygame.display.update() board = create_board() print_board(board) turn = 0#用來判斷現在是輪到玩家1還是2 game_over = False pygame.init() SQUARESIZE = 100#遊戲介面每格的大小 width = COL *SQUARESIZE#遊戲介面的寬 height = (ROW+1) * SQUARESIZE#遊戲介面的長 size = (width, height) RADIUS = int(SQUARESIZE/2 - 5)#圓的半徑 screen = pygame.display.set_mode(size) draw_board(board) pygame.display.update() myfont = pygame.font.SysFont("monospace", 75) while not game_over:#若有玩家贏了就跳出遊戲 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if event.type == pygame.MOUSEMOTION: pygame.draw.rect(screen, BLACK, (0, 0, width, SQUARESIZE)) posx = event.pos[0] if turn == 0: pygame.draw.circle(screen, RED, (posx, int(SQUARESIZE/2)), RADIUS)#玩家1的棋子 else: pygame.draw.circle(screen, YELLOW, (posx, int(SQUARESIZE/2)), RADIUS)#玩家2的棋子 pygame.display.update() if event.type == pygame.MOUSEBUTTONDOWN: #print(event.pos) #問玩家1要第幾列 if turn == 0: posx = event.pos[0] col = int(math.floor(posx/SQUARESIZE)) if is_valid_location(board, col): row = get_next_open_row(board, col) drop_piece(board, row, col, 1) if winning_move(board, 1): label = myfont.render("Player 1 wins!!!", 1, RED) screen.blit(label, (40, 10)) game_over = True #問玩家2要第幾列 else: posx = event.pos[0] col = int(math.floor(posx/SQUARESIZE)) if is_valid_location(board, col): row = get_next_open_row(board, col) drop_piece(board, row, col, 2) if winning_move(board, 2): label = myfont.render("Player 2 wins!!!", 1, YELLOW) screen.blit(label, (40, 10)) game_over = True print_board(board) draw_board(board) turn += 1 turn %= 2 if game_over: pygame.time.wait(3000) ```
{"metaMigratedAt":"2023-06-17T22:46:00.374Z","metaMigratedFrom":"YAML","title":"connect 4_2","breaks":true,"slideOptions":"{\"theme\":\"white\"}","contributors":"[{\"id\":\"4d8ac2d3-29c7-4a8e-a906-e7cdf0999b25\",\"add\":2,\"del\":2},{\"id\":\"b405d87d-0698-478c-9009-9939bd969d2c\",\"add\":15,\"del\":15},{\"id\":\"83f5b3e0-d6bd-4eaf-bceb-fc6a8dfdeecf\",\"add\":10218,\"del\":456}]","description":"相反的若要判斷斜率為負,則要尋找(i,j)、(i-1,j+1)、(i-2,j+2)、(i-3,j+3)這四個點是不是都一樣"}
    299 views
   Owned this note