Exercice formatif : Jeu de Puissance 4 en Kotlin¶
Objectif¶
Développer une version console du jeu “Puissance 4” en Kotlin. Ce travail pratique vous permettra de vous familiariser avec la syntaxe et les concepts de base de Kotlin, sans utiliser encore les fonctionnalités spécifiques à Android.
Description du jeu¶
Puissance 4 est un jeu de stratégie pour deux joueurs. Le but est d’aligner 4 jetons de sa couleur horizontalement, verticalement ou en diagonale sur une grille de 6 lignes et 7 colonnes.
Fonctionnalités requises¶
- Afficher la grille de jeu dans la console
- Permettre aux joueurs de placer leurs jetons à tour de rôle
- Vérifier la victoire après chaque coup
- Gérer les erreurs (ex : colonne pleine, entrée invalide)
- Proposer de rejouer une partie à la fin
Structure du projet¶
Voici la structure de base du projet avec le code de départ :
// Fichier: Game.kt
// package ???
enum class CellState(val symbol: Char) {
EMPTY(' '),
PLAYER_X('X'),
PLAYER_O('O');
override fun toString(): String = symbol.toString()
}
class Game {
private val board: Array<Array<CellState>> = Array(6) { Array(7) { CellState.EMPTY } }
private var currentPlayer: CellState = CellState.PLAYER_X
fun play() {
// TODO: Implémenter la logique principale du jeu
}
fun displayBoard() {
// TODO: Afficher la grille de jeu
}
fun makeMove(column: Int): Boolean {
// TODO: Placer un jeton dans la colonne spécifiée
return false
}
fun checkWin(): Boolean {
// TODO: Vérifier s'il y a un gagnant
return false
}
fun isBoardFull(): Boolean {
// TODO: Vérifier si la grille est pleine
return false
}
fun switchPlayer() {
currentPlayer = if (currentPlayer == CellState.PLAYER_X) CellState.PLAYER_O else CellState.PLAYER_X
}
fun getBoardCell(row: Int, col: Int): CellState {
return board[row][col]
}
fun getCurrentPlayer(): CellState {
return currentPlayer
}
}
// Fichier: Main.kt
fun main() {
val game = Game()
game.play()
}
Tests unitaires¶
Voici quelques tests unitaires utilisant kotlin.test :
// Fichier: GameTest.kt
import kotlin.test.*
// importer Game et CellState
class GameTest {
@Test
fun testInitialBoardIsEmpty() {
val game = Game()
for (row in 0..5) {
for (col in 0..6) {
assertEquals(CellState.EMPTY, game.getBoardCell(row, col))
}
}
}
@Test
fun testMakeValidMove() {
val game = Game()
assertTrue(game.makeMove(3))
assertEquals(CellState.PLAYER_X, game.getBoardCell(5, 3))
}
@Test
fun testMakeInvalidMove() {
val game = Game()
assertFalse(game.makeMove(7)) // Colonne invalide
assertFalse(game.makeMove(-1)) // Colonne invalide
}
@Test
fun testMakeMoveInFullColumn() {
val game = Game()
repeat(6) { game.makeMove(0) }
assertFalse(game.makeMove(0))
}
@Test
fun testSwitchPlayer() {
val game = Game()
assertEquals(CellState.PLAYER_X, game.getCurrentPlayer())
game.switchPlayer()
assertEquals(CellState.PLAYER_O, game.getCurrentPlayer())
game.switchPlayer()
assertEquals(CellState.PLAYER_X, game.getCurrentPlayer())
}
@Test
fun testCheckWinHorizontal() {
val game = Game()
repeat(4) { col ->
game.makeMove(col)
if (col < 3) game.makeMove(col)
}
assertTrue(game.checkWin())
}
@Test
fun testCheckWinVertical() {
val game = Game()
repeat(4) {
game.makeMove(0)
if (it < 3) game.makeMove(1)
}
assertTrue(game.checkWin())
}
@Test
fun testCheckWinDiagonalAscending() {
val game = Game()
game.makeMove(0); game.makeMove(1)
game.makeMove(1); game.makeMove(2)
game.makeMove(2); game.makeMove(3)
game.makeMove(2); game.makeMove(3)
game.makeMove(3); game.makeMove(0)
game.makeMove(3)
assertTrue(game.checkWin())
}
@Test
fun testCheckWinDiagonalDescending() {
val game = Game()
game.makeMove(3); game.makeMove(2)
game.makeMove(2); game.makeMove(1)
game.makeMove(1); game.makeMove(0)
game.makeMove(1); game.makeMove(0)
game.makeMove(0); game.makeMove(3)
game.makeMove(0)
assertTrue(game.checkWin())
}
@Test
fun testNoWinYet() {
val game = Game()
game.makeMove(0); game.makeMove(1)
game.makeMove(2); game.makeMove(3)
assertFalse(game.checkWin())
}
@Test
fun testIsBoardFullWhenFull() {
val game = Game()
for (col in 0..6) {
repeat(6) { game.makeMove(col) }
}
assertTrue(game.isBoardFull())
}
@Test
fun testIsBoardFullWhenNotFull() {
val game = Game()
game.makeMove(0); game.makeMove(1)
assertFalse(game.isBoardFull())
}
}
Consignes¶
- Créez un projet kotlin dans IntelliJ.
- Choisissez “Gradle” comme “Build System”, et “Kotlin” comme “Gradle DSL”.
- Complétez les fonctions de la classe
Game. - Implémentez la logique du jeu dans la fonction
play(). - Assurez-vous que le jeu gère correctement les entrées utilisateur.
- Si nécessaire, complétez et ajoutez des tests unitaires pour couvrir toutes les fonctionnalités.
- Commentez votre code de manière claire et concise.
- Au début de chaque fichier kotlin (extension
.kt), écrivez votre nom et numéro de DA dans un commentaire.
Critères d’évaluation¶
- Exercice formatif
Fonctionnalités supplémentaires¶
- Implémenter un mode contre l’ordinateur avec une IA simple
- Permettre de sauvegarder et charger une partie