TP03
This commit is contained in:
147
P4.py
Normal file
147
P4.py
Normal file
@@ -0,0 +1,147 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Connect Four (Puissance 4) — jeu console pour 2 joueurs
|
||||
Usage: python connect4.py
|
||||
Auteur: généré par ChatGPT pour Le J
|
||||
"""
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
ROWS = 6
|
||||
COLS = 7
|
||||
EMPTY = "."
|
||||
|
||||
# Symbols for players
|
||||
PLAYER_SYMBOLS = ["X", "O"]
|
||||
|
||||
def clear():
|
||||
os.system("cls" if os.name == "nt" else "clear")
|
||||
|
||||
def make_board():
|
||||
return [[EMPTY for _ in range(COLS)] for _ in range(ROWS)]
|
||||
|
||||
def print_board(board):
|
||||
clear()
|
||||
# header with column numbers
|
||||
print(" " + " ".join(str(i+1) for i in range(COLS)))
|
||||
for row in board:
|
||||
print(" |" + "|".join(row) + "|")
|
||||
print("-" * (COLS * 2 + 3))
|
||||
|
||||
def is_valid_col(board, col):
|
||||
return 0 <= col < COLS and board[0][col] == EMPTY
|
||||
|
||||
def drop_piece(board, col, symbol, animate=True):
|
||||
# find the lowest empty row
|
||||
for r in range(ROWS-1, -1, -1):
|
||||
if board[r][col] == EMPTY:
|
||||
if animate:
|
||||
# small drop animation (textual)
|
||||
for step in range(r+1):
|
||||
# draw a temporary board with the piece at current step
|
||||
temp = [row[:] for row in board]
|
||||
temp[step][col] = symbol
|
||||
print_board(temp)
|
||||
time.sleep(0.03)
|
||||
# final position
|
||||
board[r][col] = symbol
|
||||
return r, col
|
||||
return None
|
||||
|
||||
def check_direction(board, start_r, start_c, dr, dc, symbol):
|
||||
count = 0
|
||||
r, c = start_r, start_c
|
||||
# go backwards
|
||||
while 0 <= r < ROWS and 0 <= c < COLS and board[r][c] == symbol:
|
||||
count += 1
|
||||
r -= dr
|
||||
c -= dc
|
||||
# go forward (excluding start)
|
||||
r, c = start_r + dr, start_c + dc
|
||||
while 0 <= r < ROWS and 0 <= c < COLS and board[r][c] == symbol:
|
||||
count += 1
|
||||
r += dr
|
||||
c += dc
|
||||
return count
|
||||
|
||||
def is_winner(board, r, c, symbol):
|
||||
# check horizontal (0,1), vertical (1,0), diag up-right (1,1), diag down-right (1,-1)
|
||||
directions = [(0,1), (1,0), (1,1), (1,-1)]
|
||||
for dr, dc in directions:
|
||||
if check_direction(board, r, c, dr, dc, symbol) >= 4:
|
||||
return True
|
||||
return False
|
||||
|
||||
def board_full(board):
|
||||
return all(cell != EMPTY for cell in board[0])
|
||||
|
||||
def ask_column(player):
|
||||
while True:
|
||||
choice = input(f"Joueur {player+1} ({PLAYER_SYMBOLS[player]}), choisis une colonne (1-{COLS}) ou 'q' pour quitter: ").strip()
|
||||
if choice.lower() == 'q':
|
||||
return "q"
|
||||
if not choice.isdigit():
|
||||
print("Entrée invalide — entre un numéro.")
|
||||
continue
|
||||
col = int(choice) - 1
|
||||
if col < 0 or col >= COLS:
|
||||
print(f"Choisis une colonne entre 1 et {COLS}.")
|
||||
continue
|
||||
return col
|
||||
|
||||
def main():
|
||||
print("=== Connect Four (Puissance 4) — 2 joueurs ===")
|
||||
print("Règles rapides : place ton jeton dans une colonne ; il tombe tout en bas ou sur le dernier jeton.")
|
||||
print("Le premier qui aligne 4 jetons de suite (horizontale, verticale ou diagonale) gagne.")
|
||||
print("Appuie sur Entrée pour commencer...")
|
||||
input()
|
||||
while True:
|
||||
board = make_board()
|
||||
current = 0 # joueur 0 commence
|
||||
winner = None
|
||||
|
||||
print_board(board)
|
||||
while True:
|
||||
col = ask_column(current)
|
||||
if col == "q":
|
||||
print("Partie quittée. À plus !")
|
||||
return
|
||||
if not is_valid_col(board, col):
|
||||
print("Colonne pleine ou invalide, choisis-en une autre.")
|
||||
time.sleep(0.7)
|
||||
continue
|
||||
|
||||
# drop piece (with animation)
|
||||
r, c = drop_piece(board, col, PLAYER_SYMBOLS[current], animate=True)
|
||||
print_board(board)
|
||||
|
||||
# check win
|
||||
if is_winner(board, r, c, PLAYER_SYMBOLS[current]):
|
||||
winner = current
|
||||
break
|
||||
|
||||
# check draw
|
||||
if board_full(board):
|
||||
break
|
||||
|
||||
# next player
|
||||
current = 1 - current
|
||||
|
||||
if winner is not None:
|
||||
print(f"🎉 Joueur {winner+1} ({PLAYER_SYMBOLS[winner]}) a gagné ! Bravo !")
|
||||
else:
|
||||
print("Match nul — le tableau est plein.")
|
||||
|
||||
# play again?
|
||||
again = input("Rejouer ? (o/n) : ").strip().lower()
|
||||
if again not in ("o", "oui", "y", "yes"):
|
||||
print("Merci d'avoir joué — à la prochaine !")
|
||||
break
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main()
|
||||
except KeyboardInterrupt:
|
||||
print("\nInterrompu — bye !")
|
||||
Reference in New Issue
Block a user