Merge pull request 'Tp1' (#1) from Tp1 into master

Reviewed-on: #1
pull/3/head
Louis DUFOUR 2 years ago
commit 8c8740d6c3

@ -0,0 +1,312 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
167C5A152B57F0BC006FB682 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 167C5A142B57F0BC006FB682 /* main.swift */; };
16CE03F62B57F58E00A85305 /* Extension in Frameworks */ = {isa = PBXBuildFile; productRef = 16CE03F52B57F58E00A85305 /* Extension */; };
16CE03F82B57F59200A85305 /* Model in Frameworks */ = {isa = PBXBuildFile; productRef = 16CE03F72B57F59200A85305 /* Model */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
167C5A0F2B57F0BC006FB682 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = /usr/share/man/man1/;
dstSubfolderSpec = 0;
files = (
);
runOnlyForDeploymentPostprocessing = 1;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
167C5A112B57F0BC006FB682 /* DouShouQiConsole */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = DouShouQiConsole; sourceTree = BUILT_PRODUCTS_DIR; };
167C5A142B57F0BC006FB682 /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
167C5A0E2B57F0BC006FB682 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
16CE03F82B57F59200A85305 /* Model in Frameworks */,
16CE03F62B57F58E00A85305 /* Extension in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
167C5A082B57F0BC006FB682 = {
isa = PBXGroup;
children = (
167C5A132B57F0BC006FB682 /* DouShouQiConsole */,
167C5A122B57F0BC006FB682 /* Products */,
16CE03F42B57F58E00A85305 /* Frameworks */,
);
sourceTree = "<group>";
};
167C5A122B57F0BC006FB682 /* Products */ = {
isa = PBXGroup;
children = (
167C5A112B57F0BC006FB682 /* DouShouQiConsole */,
);
name = Products;
sourceTree = "<group>";
};
167C5A132B57F0BC006FB682 /* DouShouQiConsole */ = {
isa = PBXGroup;
children = (
167C5A142B57F0BC006FB682 /* main.swift */,
);
path = DouShouQiConsole;
sourceTree = "<group>";
};
16CE03F42B57F58E00A85305 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
167C5A102B57F0BC006FB682 /* DouShouQiConsole */ = {
isa = PBXNativeTarget;
buildConfigurationList = 167C5A182B57F0BC006FB682 /* Build configuration list for PBXNativeTarget "DouShouQiConsole" */;
buildPhases = (
167C5A0D2B57F0BC006FB682 /* Sources */,
167C5A0E2B57F0BC006FB682 /* Frameworks */,
167C5A0F2B57F0BC006FB682 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = DouShouQiConsole;
packageProductDependencies = (
16CE03F52B57F58E00A85305 /* Extension */,
16CE03F72B57F59200A85305 /* Model */,
);
productName = DouShouQiConsole;
productReference = 167C5A112B57F0BC006FB682 /* DouShouQiConsole */;
productType = "com.apple.product-type.tool";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
167C5A092B57F0BC006FB682 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1420;
LastUpgradeCheck = 1420;
TargetAttributes = {
167C5A102B57F0BC006FB682 = {
CreatedOnToolsVersion = 14.2;
};
};
};
buildConfigurationList = 167C5A0C2B57F0BC006FB682 /* Build configuration list for PBXProject "DouShouQiConsole" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 167C5A082B57F0BC006FB682;
productRefGroup = 167C5A122B57F0BC006FB682 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
167C5A102B57F0BC006FB682 /* DouShouQiConsole */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
167C5A0D2B57F0BC006FB682 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
167C5A152B57F0BC006FB682 /* main.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
167C5A162B57F0BC006FB682 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 13.1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
167C5A172B57F0BC006FB682 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MACOSX_DEPLOYMENT_TARGET = 13.1;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
167C5A192B57F0BC006FB682 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
};
name = Debug;
};
167C5A1A2B57F0BC006FB682 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
167C5A0C2B57F0BC006FB682 /* Build configuration list for PBXProject "DouShouQiConsole" */ = {
isa = XCConfigurationList;
buildConfigurations = (
167C5A162B57F0BC006FB682 /* Debug */,
167C5A172B57F0BC006FB682 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
167C5A182B57F0BC006FB682 /* Build configuration list for PBXNativeTarget "DouShouQiConsole" */ = {
isa = XCConfigurationList;
buildConfigurations = (
167C5A192B57F0BC006FB682 /* Debug */,
167C5A1A2B57F0BC006FB682 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
16CE03F52B57F58E00A85305 /* Extension */ = {
isa = XCSwiftPackageProductDependency;
productName = Extension;
};
16CE03F72B57F59200A85305 /* Model */ = {
isa = XCSwiftPackageProductDependency;
productName = Model;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 167C5A092B57F0BC006FB682 /* Project object */;
}

@ -0,0 +1,64 @@
//
// main.swift
// ProjectDouShouQi
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
import Model
import Extension
let initialBoardConfiguration: [[Cell]] = [
// Ligne 1
[Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .lion)),
Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .den), Cell(ofType: .trap),
Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .tiger))],
// Ligne 2
[Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .dog)),
Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .jungle),
Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .cat)), Cell(ofType: .jungle)],
// Ligne 3
[Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .rat)),
Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .leopard)),
Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .wolf)),
Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player1, andAnimal: .elephant))],
// Lignes 4 à 7 (Eau et Jungle)
[Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water),
Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)],
[Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water),
Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)],
[Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water),
Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)],
[Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water),
Cell(ofType: .jungle), Cell(ofType: .water), Cell(ofType: .water), Cell(ofType: .jungle)],
// Ligne 8
[Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .elephant)),
Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .wolf)),
Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .leopard)),
Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .rat))],
// Ligne 9
[Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .cat)),
Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .jungle),
Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .dog)), Cell(ofType: .jungle)],
// Ligne 10
[Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .tiger)),
Cell(ofType: .jungle), Cell(ofType: .trap), Cell(ofType: .den), Cell(ofType: .trap),
Cell(ofType: .jungle), Cell(ofType: .jungle, withPiece: Piece(withOwner: .player2, andAnimal: .lion))]
]
if let board = Board(withGrid: initialBoardConfiguration) {
// Afficher le plateau de jeu
print(board.display())
} else {
print("Erreur lors de l'initialisation du plateau de jeu.")
}

@ -0,0 +1,9 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc

@ -0,0 +1,29 @@
// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Extension",
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "Extension",
targets: ["Extension"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
.package(path: "../Model"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "Extension",
dependencies: ["Model"]),
.testTarget(
name: "ExtensionTests",
dependencies: ["Extension", "Model"]),
]
)

@ -0,0 +1,3 @@
# Extension
A description of this package.

@ -0,0 +1,24 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
import Model
public extension Animal {
var symbol: String {
switch self {
case .rat: return "🐭"
case .cat: return "🐱"
case .dog: return "🐶"
case .wolf: return "🐺"
case .leopard: return "🐆"
case .tiger: return "🐯"
case .lion: return "🦁"
case .elephant: return "🐘"
}
}
}

@ -0,0 +1,24 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
import Model
public extension Board {
func display() {
for row in grid {
for cell in row {
if let piece = cell.piece {
print(cell.cellType.symbol + piece.owner.symbol + piece.animal.symbol, terminator: " ")}
else {
print(cell.cellType.symbol, terminator: " ")}
}
print()
}
}
}

@ -0,0 +1,21 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
import Model
public extension CellType {
var symbol: String {
switch self {
case .unknown: return " "
case .jungle: return "🌿"
case .water: return "💧"
case .trap: return "🪤"
case .den: return "🪹"
}
}
}

@ -0,0 +1,19 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
import Model
public extension Owner {
var symbol: String {
switch self {
case .noOne: return " "
case .player1: return "🟡"
case .player2: return "🔴"
}
}
}

@ -0,0 +1,13 @@
import XCTest
@testable import Extension
/*
final class ExtensionTests: XCTestCase {
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
XCTAssertEqual(Extension().text, "Hello, World!")
}
}
*/

9
Model/.gitignore vendored

@ -0,0 +1,9 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/config/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc

@ -0,0 +1,28 @@
// swift-tools-version: 5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "Model",
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "Model",
targets: ["Model"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "Model",
dependencies: []),
.testTarget(
name: "ModelTests",
dependencies: ["Model"]),
]
)

@ -0,0 +1,3 @@
# Model
A description of this package.

@ -0,0 +1,34 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
public enum Animal: String { case rat, cat, dog, wolf, leopard, tiger, lion, elephant
public var description: String {
switch self {
case .rat:
return "Rat"
case .cat:
return "Cat"
case .dog:
return "Dog"
case .wolf:
return "Wolf"
case .leopard:
return "Leopard"
case .tiger:
return "Tiger"
case .lion:
return "Lion"
case .elephant:
return "Elephant"
}
}
}

@ -0,0 +1,44 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
public struct Board {
let nbRows: Int
let nbColumns: Int
public var grid: [[Cell]]
public init?(withGrid grid: [[Cell]]) {
guard let firstRowLength = grid.first?.count, grid.allSatisfy({ $0.count == firstRowLength }) else {
return nil
}
self.nbRows = grid.count
self.nbColumns = firstRowLength
self.grid=grid
}
func getCell(atRow row: Int, column: Int) -> Cell? {
guard row >= 0, row < nbRows, column >= 0, column < nbColumns else {
return nil
}
return grid[row][column]
}
public var description: String {
var boardDescription = ""
for row in grid {
for cell in row {
boardDescription += cell.description + " "
}
boardDescription += "\n"
}
return boardDescription
}
}

@ -0,0 +1,31 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
public struct Cell {
public let cellType: CellType
public var initialOwner: Owner
public var piece: Piece?
public init(ofType cellType: CellType, ownedBy initialOwner: Owner = .noOne, withPiece piece: Piece? = nil) {
self.cellType = cellType
self.initialOwner = initialOwner
self.piece = piece
}
public var description: String {
var pieceDescription = "nil"
if let piece = piece {
pieceDescription = piece.description
}
return "Cell(type: (cellType), owner: (initialOwner), piece: (pieceDescription))"
}
}

@ -0,0 +1,28 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
public enum CellType {
case unknown, jungle, water, trap, den
public var description: String {
switch self {
case .unknown:
return "unknown cell"
case .jungle:
return "jungle cell"
case .water:
return "water cell"
case .trap:
return "trap cell"
case .den:
return "den cell"
}
}
}

@ -0,0 +1,25 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
public enum Owner {
case noOne, player1, player2
public var description: String {
switch self {
case .player1:
return "1"
case .player2:
return "2"
case .noOne:
return "x"
}
}
}

@ -0,0 +1,22 @@
//
// File.swift
//
//
// Created by Louis DUFOUR on 15/01/2024.
//
import Foundation
public struct Piece {
public let owner: Owner
public let animal: Animal
public init(withOwner owner: Owner, andAnimal animal: Animal) {
self.owner = owner
self.animal = animal
}
public var description: String {
return "[(owner):(animal)]"
}
}

@ -0,0 +1,13 @@
import XCTest
@testable import Model
/*
final class ModelTests: XCTestCase {
func testExample() throws {
// This is an example of a functional test case.
// Use XCTAssert and related functions to verify your tests produce the correct
// results.
XCTAssertEqual(Model().text, "Hello, World!")
}
}
*/

@ -1,196 +1,32 @@
**Home** | [Semaine 1](./subject_week1.md)
# Introduction
# Projet DouShouQi en Swift
- [Introduction](#introduction)
- [Dou Shou Qi](#dou-shou-qi)
- [**But du jeu** :](#but-du-jeu-)
- [**Matériel** :](#matériel-)
- [Pouvoir des animaux](#pouvoir-des-animaux)
- [Déroulement du jeu](#déroulement-du-jeu)
- [Déroulement des TP](#déroulement-des-tp)
- [Évaluation](#évaluation)
- [Structure de l'application](#structure-de-lapplication)
- [Énoncés](#énoncés)
## Introduction
Le projet DouShouQi en Swift est une implémentation console du jeu de plateau DouShouQi.
## Prérequis
- **Système d'exploitation**: macOS Ventura 13.1
- **Logiciel**: Xcode version 14.2
Cette introduction explique comment cette ressource va se dérouler, ce qu'il y aura à réaliser, et comment vous serez évaluées et évalués.
Pour découvrir le langage **Swift**, nous proposons de développer le modèle d'un jeu traditionnel chinois appelé le **Dou Shou Qi** dont les origines remontraient au Vème siècle.
# Dou Shou Qi
## **But du jeu** :
- occuper la tanière de son adversaire
- ou manger toutes ses pièces
- ou l'empêcher de bouger.
## **Matériel** :
Chaque joueur possède 8 pions numérotés (pour représenter leur force) et représentant des animaux : **Rat** 🐭 (1), **Chat** 🐱 (2), **Chien** 🐶 (3), **Loup** 🐺 (4), **Léopard** 🐆 (5), **Tigre** 🐯 (6), **Lion** 🦁 (7) et **Éléphant** 🐘 (8).
Le plateau de jeu est une grille à deux dimensions de 10 lignes et 7 colonnes. Il est fait de 4 types de cases :
- **Jungle** 🌿 : aucune particularité
- **Lac** 💧 : interdit à tous les animaux sauf le **Rat** ; le **Lion** et le **Tigre** peuvent sauter par-dessus.
- **Tanière** 🪹 : un joueur ne peut pas se déplacer sur sa propre **Tanière** et doit aller sur la **Tanière** de l'adversaire pour gagner
- **Piège** 🪤 : un pion sur un piège (quel que soit le côté du plateau) a une force de **0**.
La grille originale ressemble à :
🌿 🌿 🪤 🪹 🪤 🌿 🌿
🌿 🌿 🌿 🪤 🌿 🌿 🌿
🌿 🌿 🌿 🌿 🌿 🌿 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 🌿 🌿 🌿 🌿 🌿 🌿
🌿 🌿 🌿 🪤 🌿 🌿 🌿
🌿 🌿 🪤 🪹 🪤 🌿 🌿
(la tanière du haut est celle du joueur 1, celle du bas du joueur 2).
De plus, certaines cases sont les cases de départ des pions :
🦁 🌿 🪤 🪹 🪤 🌿 🐯
🌿 🐶 🌿 🪤 🌿 🐱 🌿
🐭 🌿 🐆 🌿 🐺 🌿 🐘
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🐘 🌿 🐺 🌿 🐆 🌿 🐭
🌿 🐱 🌿 🪤 🌿 🐶 🌿
🐯 🌿 🪤 🪹 🪤 🌿 🦁
(où les animaux du haut sont ceux du joueur 1, et ceux du bas du joueur 2).
## Pouvoir des animaux
- Tous les animaux peuvent _manger_ un animal de force égale ou inférieure, avec les exceptions suivantes :
- l'éléphant ne peut pas _manger_ le rat,
- le rat peut _manger_ l'éléphant,
- on ne peut pas _manger_ son propre animal.
- Les animaux ne peuvent se déplacer que sur une case adjacente (même ligne ou même colonne)
- Les animaux ne peuvent pas se déplacer sur leur propre **Tanière**
- Les animaux ne peuvent pas se déplacer dans l'eau (sauf le **Rat**). Attention, le **Rat** ne peut pas sortir de l'eau pour attaquer l'**éléphant** adverse, mais il peut le faire pour attaquer le **rat** adverse.
- Le **lion** et le **tigre** peuvent sauter par-dessus les lacs (en restant sur la même ligne ou sur la même colonne), **sauf** si un **rat** est dans le lac, sur la trajectoire du saut.
## Déroulement du jeu
Chaque joueur doit à son tour de jeu déplacer l'un de ses animaux.
# Déroulement des TP
L'objectif des TP est de réaliser cette application en 5 TP durant 6 semaines.
Les énoncés seront donnés en début de semaine ainsi qu'une liste de thème à travailler pour bien réussir le TP.
La sixième semaine sert de tampon, pour rattraper le retard accumulé pendant les semaines précédentes.
Pour chacune des 5 premières semaines, il est conseillé de :
- avant le TP :
- travailler les thèmes donnés en avance, via :
- la [documentation officielle du langage Swift](https://www.swift.org/documentation/)
- le [livre Apple sur le langage Swift](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/)
- les [ressources de cours sur code first](https://codefirst.iut.uca.fr/documentation/mchCoursDocusaurus/docusaurus/Swift/)
- profiter du résumé en cours et poser des questions sur les parties non comprises
- pendant le TP :
- réaliser au maximum les tâches demandées
- et les faire valider par l'enseignant pour obtenir validation de l'acquisition des compétences
- après le TP :
- faire le point sur le "reste à faire" et s'organiser pour la semaine suivante
- faire le point sur les acquis que vous n'avez pas fait valider pour solliciter l'enseignant à la séance suivante
Pour la sixième semaine :
- profiter du dernier cours pour poser les dernières questions techniques
- profiter du dernier TP pour rattraper le retard et faire valider ses derniers acquis non validés par l'enseignant.
> Note :
> Les ressources de cours sur code first ne remplacent pas la documentation officielle. Elles apportent des conseils sur l'ordre de lecture dans la réalisation des TP.
>
# Évaluation
Une fiche de compétences à acquérir et des points à réaliser en TP sera préparée et accessible pour chaque TP sur code first.
Vous aurez accès aux évaluations de l'enseignant au fur et à mesure de son évaluation.
Pour obtenir une validation, vous devrez prouver votre acquisition des compétences à l'enseignant via : un entretien oral ou un examen écrit.
La note finale sera composée de l'ensemble des acquis validés par l'enseignant à la dernière minute du dernier TP.
# Structure de l'application
Voici un diagramme de classes volontairement simplifié présentant grossièrement les différents acteurs de l'application que vous devez réaliser :
```mermaid
classDiagram
direction TB
Game --> "1" Rules : rules
Game --> "1" Board : board
Game --> "2" Player: players
Rules <|.. ClassicRules
Rules <|.. VerySimpleRules
Rules ..> Board
Board --> "*,*" Cell : grid
Player <|-- RandomPlayer
Player <|-- HumanPlayer
class Board {
+insert(piece:, atRow:, andColumn:)
+removePiece(atRow:, andColumn:)
}
class Cell {
+cellType : CellType
+initialOwner: Owner
+piece : Piece?
}
class Rules {
+createBoard() : Board$
+getNextPlayer() : Owner
+isMoveValid(Board, Move) : Bool
+isGameOver(Board, Int, Int) : Bool
}
class Player {
+chooseMove(in: Board, with: Rules) Move?
}
class Game {
+init(withRules:, andPlayer1:, andPlayer2: Player)
+start()
}
## Installation et Configuration
### Étape 1 : Clonage du projet
```
git clone <lien-du-projet>
```
- ```Board``` représente le plateau de jeu et est composé d'un tableau à deux dimensions de ```Cell``` : il est responsable de l'insertion, de la suppression et donc du déplacement des pions.
- ```Rules``` représente les règles du jeu. Comme elles sont assez touffues (```ClassicRules```), je vous proposerai des règles simplifiées (```VerySimpleRules```). ```Rules``` indique qui est le prochain joueur, si un coup est valide, si la partie est terminée, etc.
- ```Player``` représente un joueur. Nous en réaliserons deux versions en particulier : une *IA* qui jouera aléatoirement (```RandomPlayer```) et un joueur humain (```HumanPlayer```).
- ```Game``` : sert de médiateur et d'ordonnanceur pour la gestion globale du jeu.
L'application à réaliser est une application en lignes de commandes qui permettra de jouer dans un terminal et ressemblera au résultat ci-dessous :
<img src="./images/Terminal.png" width="600px"/>
Vous travaillerez sur :
- ```Board``` et ```Cell``` pendant les deux premières semaines,
- ```Rules``` et ```VerySimpleRules``` pendant la 3ème semaine,
- ```Player```, ```RandomPlayer``` et ```HumanPlayer``` pendant la 4ème semaine,
- ```Game``` et l'application finale pendant la 5ème semaine.
Des énoncés plus détaillés vous seront donnés au début de chaque semaine.
# Énoncés
- [Semaine 1](./subject_week1.md)
**Home** | [Semaine 1](./subject_week1.md)
---
Copyright &copy; 2023-2024 Marc Chevaldonné
While writing this tutorial, I was listening to...
<table>
<tr>
<td>
<img src="./images/listeningto/on_the_corner.jpg" width="120"/>
</td>
<td>
<div>
<p><b>On The Corner</b></p>
<p><i>Miles Davis</i> (1972)</p>
</div>
</td>
</tr>
</table>
### Étape 2 : Ouvrir le projet dans Xcode
- Ouvrez Xcode.
- Cliquez sur "File" (Fichier) dans la barre de menu.
- Sélectionnez "Open" (Ouvrir).
- Naviguez jusqu'au répertoire où vous avez cloné le projet et ouvrez le fichier `.xcodeproj`.
### Étape 3 : Compilation et exécution
- Appuyez sur le bouton de lecture (triangle vert) dans Xcode pour compiler et exécuter le projet.
## Problèmes Connus et Solutions
- Refaire une structure de projet
- Un autre truc sur tostring
- On peu pas lire Owner, car internal (donc getter)
- Pareil pour cell
- Pareil pour board (peux pas la lire)
- Juste faire un print de board

@ -0,0 +1,196 @@
**Home** | [Semaine 1](./subject_week1.md)
# Introduction
- [Introduction](#introduction)
- [Dou Shou Qi](#dou-shou-qi)
- [**But du jeu** :](#but-du-jeu-)
- [**Matériel** :](#matériel-)
- [Pouvoir des animaux](#pouvoir-des-animaux)
- [Déroulement du jeu](#déroulement-du-jeu)
- [Déroulement des TP](#déroulement-des-tp)
- [Évaluation](#évaluation)
- [Structure de l'application](#structure-de-lapplication)
- [Énoncés](#énoncés)
Cette introduction explique comment cette ressource va se dérouler, ce qu'il y aura à réaliser, et comment vous serez évaluées et évalués.
Pour découvrir le langage **Swift**, nous proposons de développer le modèle d'un jeu traditionnel chinois appelé le **Dou Shou Qi** dont les origines remontraient au Vème siècle.
# Dou Shou Qi
## **But du jeu** :
- occuper la tanière de son adversaire
- ou manger toutes ses pièces
- ou l'empêcher de bouger.
## **Matériel** :
Chaque joueur possède 8 pions numérotés (pour représenter leur force) et représentant des animaux : **Rat** 🐭 (1), **Chat** 🐱 (2), **Chien** 🐶 (3), **Loup** 🐺 (4), **Léopard** 🐆 (5), **Tigre** 🐯 (6), **Lion** 🦁 (7) et **Éléphant** 🐘 (8).
Le plateau de jeu est une grille à deux dimensions de 10 lignes et 7 colonnes. Il est fait de 4 types de cases :
- **Jungle** 🌿 : aucune particularité
- **Lac** 💧 : interdit à tous les animaux sauf le **Rat** ; le **Lion** et le **Tigre** peuvent sauter par-dessus.
- **Tanière** 🪹 : un joueur ne peut pas se déplacer sur sa propre **Tanière** et doit aller sur la **Tanière** de l'adversaire pour gagner
- **Piège** 🪤 : un pion sur un piège (quel que soit le côté du plateau) a une force de **0**.
La grille originale ressemble à :
🌿 🌿 🪤 🪹 🪤 🌿 🌿
🌿 🌿 🌿 🪤 🌿 🌿 🌿
🌿 🌿 🌿 🌿 🌿 🌿 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 🌿 🌿 🌿 🌿 🌿 🌿
🌿 🌿 🌿 🪤 🌿 🌿 🌿
🌿 🌿 🪤 🪹 🪤 🌿 🌿
(la tanière du haut est celle du joueur 1, celle du bas du joueur 2).
De plus, certaines cases sont les cases de départ des pions :
🦁 🌿 🪤 🪹 🪤 🌿 🐯
🌿 🐶 🌿 🪤 🌿 🐱 🌿
🐭 🌿 🐆 🌿 🐺 🌿 🐘
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🌿 💧 💧 🌿 💧 💧 🌿
🐘 🌿 🐺 🌿 🐆 🌿 🐭
🌿 🐱 🌿 🪤 🌿 🐶 🌿
🐯 🌿 🪤 🪹 🪤 🌿 🦁
(où les animaux du haut sont ceux du joueur 1, et ceux du bas du joueur 2).
## Pouvoir des animaux
- Tous les animaux peuvent _manger_ un animal de force égale ou inférieure, avec les exceptions suivantes :
- l'éléphant ne peut pas _manger_ le rat,
- le rat peut _manger_ l'éléphant,
- on ne peut pas _manger_ son propre animal.
- Les animaux ne peuvent se déplacer que sur une case adjacente (même ligne ou même colonne)
- Les animaux ne peuvent pas se déplacer sur leur propre **Tanière**
- Les animaux ne peuvent pas se déplacer dans l'eau (sauf le **Rat**). Attention, le **Rat** ne peut pas sortir de l'eau pour attaquer l'**éléphant** adverse, mais il peut le faire pour attaquer le **rat** adverse.
- Le **lion** et le **tigre** peuvent sauter par-dessus les lacs (en restant sur la même ligne ou sur la même colonne), **sauf** si un **rat** est dans le lac, sur la trajectoire du saut.
## Déroulement du jeu
Chaque joueur doit à son tour de jeu déplacer l'un de ses animaux.
# Déroulement des TP
L'objectif des TP est de réaliser cette application en 5 TP durant 6 semaines.
Les énoncés seront donnés en début de semaine ainsi qu'une liste de thème à travailler pour bien réussir le TP.
La sixième semaine sert de tampon, pour rattraper le retard accumulé pendant les semaines précédentes.
Pour chacune des 5 premières semaines, il est conseillé de :
- avant le TP :
- travailler les thèmes donnés en avance, via :
- la [documentation officielle du langage Swift](https://www.swift.org/documentation/)
- le [livre Apple sur le langage Swift](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/)
- les [ressources de cours sur code first](https://codefirst.iut.uca.fr/documentation/mchCoursDocusaurus/docusaurus/Swift/)
- profiter du résumé en cours et poser des questions sur les parties non comprises
- pendant le TP :
- réaliser au maximum les tâches demandées
- et les faire valider par l'enseignant pour obtenir validation de l'acquisition des compétences
- après le TP :
- faire le point sur le "reste à faire" et s'organiser pour la semaine suivante
- faire le point sur les acquis que vous n'avez pas fait valider pour solliciter l'enseignant à la séance suivante
Pour la sixième semaine :
- profiter du dernier cours pour poser les dernières questions techniques
- profiter du dernier TP pour rattraper le retard et faire valider ses derniers acquis non validés par l'enseignant.
> Note :
> Les ressources de cours sur code first ne remplacent pas la documentation officielle. Elles apportent des conseils sur l'ordre de lecture dans la réalisation des TP.
>
# Évaluation
Une fiche de compétences à acquérir et des points à réaliser en TP sera préparée et accessible pour chaque TP sur code first.
Vous aurez accès aux évaluations de l'enseignant au fur et à mesure de son évaluation.
Pour obtenir une validation, vous devrez prouver votre acquisition des compétences à l'enseignant via : un entretien oral ou un examen écrit.
La note finale sera composée de l'ensemble des acquis validés par l'enseignant à la dernière minute du dernier TP.
# Structure de l'application
Voici un diagramme de classes volontairement simplifié présentant grossièrement les différents acteurs de l'application que vous devez réaliser :
```mermaid
classDiagram
direction TB
Game --> "1" Rules : rules
Game --> "1" Board : board
Game --> "2" Player: players
Rules <|.. ClassicRules
Rules <|.. VerySimpleRules
Rules ..> Board
Board --> "*,*" Cell : grid
Player <|-- RandomPlayer
Player <|-- HumanPlayer
class Board {
+insert(piece:, atRow:, andColumn:)
+removePiece(atRow:, andColumn:)
}
class Cell {
+cellType : CellType
+initialOwner: Owner
+piece : Piece?
}
class Rules {
+createBoard() : Board$
+getNextPlayer() : Owner
+isMoveValid(Board, Move) : Bool
+isGameOver(Board, Int, Int) : Bool
}
class Player {
+chooseMove(in: Board, with: Rules) Move?
}
class Game {
+init(withRules:, andPlayer1:, andPlayer2: Player)
+start()
}
```
- ```Board``` représente le plateau de jeu et est composé d'un tableau à deux dimensions de ```Cell``` : il est responsable de l'insertion, de la suppression et donc du déplacement des pions.
- ```Rules``` représente les règles du jeu. Comme elles sont assez touffues (```ClassicRules```), je vous proposerai des règles simplifiées (```VerySimpleRules```). ```Rules``` indique qui est le prochain joueur, si un coup est valide, si la partie est terminée, etc.
- ```Player``` représente un joueur. Nous en réaliserons deux versions en particulier : une *IA* qui jouera aléatoirement (```RandomPlayer```) et un joueur humain (```HumanPlayer```).
- ```Game``` : sert de médiateur et d'ordonnanceur pour la gestion globale du jeu.
L'application à réaliser est une application en lignes de commandes qui permettra de jouer dans un terminal et ressemblera au résultat ci-dessous :
<img src="./images/Terminal.png" width="600px"/>
Vous travaillerez sur :
- ```Board``` et ```Cell``` pendant les deux premières semaines,
- ```Rules``` et ```VerySimpleRules``` pendant la 3ème semaine,
- ```Player```, ```RandomPlayer``` et ```HumanPlayer``` pendant la 4ème semaine,
- ```Game``` et l'application finale pendant la 5ème semaine.
Des énoncés plus détaillés vous seront donnés au début de chaque semaine.
# Énoncés
- [Semaine 1](./subject_week1.md)
**Home** | [Semaine 1](./subject_week1.md)
---
Copyright &copy; 2023-2024 Marc Chevaldonné
While writing this tutorial, I was listening to...
<table>
<tr>
<td>
<img src="./images/listeningto/on_the_corner.jpg" width="120"/>
</td>
<td>
<div>
<p><b>On The Corner</b></p>
<p><i>Miles Davis</i> (1972)</p>
</div>
</td>
</tr>
</table>

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:DouShouQiConsole/DouShouQiConsole.xcodeproj">
</FileRef>
<FileRef
location = "group:Extension">
</FileRef>
<FileRef
location = "group:Model">
</FileRef>
</Workspace>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
Loading…
Cancel
Save