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!")
|
||||
}
|
||||
}
|
||||
*/
|
@ -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 © 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 © 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…
Reference in new issue