WIP: New Game view

main
Mathieu GROUSSEAU 1 month ago
parent 9dae915bcd
commit 37f67c603e

@ -20,6 +20,7 @@
F0F59E4C2DD4958800BE32D6 /* C4Rules.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = F0F59E442DD492B400BE32D6 /* C4Rules.xcframework */; };
F0F59E4F2DD4996F00BE32D6 /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = F0F59E4E2DD4996F00BE32D6 /* Localizable.xcstrings */; };
F0F59E512DD49C2800BE32D6 /* Colors.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F0F59E502DD49C2800BE32D6 /* Colors.xcassets */; };
F0F59E532DDDC35100BE32D6 /* NewGameView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0F59E522DDDC35100BE32D6 /* NewGameView.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@ -57,6 +58,7 @@
F0F59E442DD492B400BE32D6 /* C4Rules.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = C4Rules.xcframework; path = ../precompiled/xcframeworks/C4Rules.xcframework; sourceTree = "<group>"; };
F0F59E4E2DD4996F00BE32D6 /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = Localizable.xcstrings; path = App/Localizable.xcstrings; sourceTree = "<group>"; };
F0F59E502DD49C2800BE32D6 /* Colors.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Colors.xcassets; sourceTree = "<group>"; };
F0F59E522DDDC35100BE32D6 /* NewGameView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewGameView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -163,6 +165,7 @@
isa = PBXGroup;
children = (
F001A04D2DD48FAB00809561 /* MainMenuView.swift */,
F0F59E522DDDC35100BE32D6 /* NewGameView.swift */,
);
path = View;
sourceTree = "<group>";
@ -302,6 +305,7 @@
files = (
F001A04E2DD48FAB00809561 /* MainMenuView.swift in Sources */,
F001A04C2DD48FAB00809561 /* AppApp.swift in Sources */,
F0F59E532DDDC35100BE32D6 /* NewGameView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

@ -35,6 +35,125 @@
}
}
},
"generic.player.type.aiFinnishHim" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "(AI) Finnish Him"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "(IA) Finnish Him"
}
}
}
},
"generic.player.type.aiRandom" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "(AI) Random"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "(IA) Aléatoire"
}
}
}
},
"generic.player.type.aiSimpleNegaMax" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "(AI) Simple NegaMax"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "(IA) NegaMax Simple"
}
}
}
},
"generic.player.type.human" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Human"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Humain"
}
}
}
},
"generic.player1.name" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Player 1"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Joueur 1"
}
}
}
},
"generic.player2.name" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Player 2"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Joueur 2"
}
}
}
},
"generic.rules.classic.name" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Classic"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Classique"
}
}
}
},
"mainMenu.button.newGame" : {
"extractionState" : "manual",
"localizations" : {
@ -68,6 +187,173 @@
}
}
}
},
"newGame.dimensions" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dimensions"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Dimensions"
}
}
}
},
"newGame.dimensions.alignedTokens %llu" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Tokens to align: %llu"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Jetons à aligner: %llu"
}
}
}
},
"newGame.dimensions.height %llu" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "%llu rows"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "%llu lignes"
}
}
}
},
"newGame.dimensions.width %llu" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "%llu columns"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "%llu colonnes"
}
}
}
},
"newGame.play" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Play"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Jouer"
}
}
}
},
"newGame.player.name" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Name"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nom"
}
}
}
},
"newGame.player.photo.picker" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Photo"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Photo"
}
}
}
},
"newGame.player.type" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Player"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Joueur"
}
}
}
},
"newGame.rules.title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Rules"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Règles"
}
}
}
},
"newGame.title" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "New Game"
}
},
"fr" : {
"stringUnit" : {
"state" : "translated",
"value" : "Nouvelle partie"
}
}
}
}
},
"version" : "1.0"

@ -0,0 +1,100 @@
//
// NewGameView.swift
// App
//
// Created by etudiant2 on 21/05/2025.
//
import SwiftUI
import PhotosUI
struct NewGameView: View {
@State private var p2: PlayerType = .AISimpleNegaMax
@State private var rules_type: RulesType = .Classic
@State private var width: UInt = 7
@State private var height: UInt = 7
@State private var alignedTokens: UInt = 4
var body: some View {
VStack {
Form {
Section("generic.player1.name") {
PlayerSectionView(initialType: .Human)
}
Section("generic.player2.name") {
PlayerSectionView(initialType: .AISimpleNegaMax)
}
HStack {
Picker("newGame.rules.title", systemImage: "globe", selection: $rules_type) {
Text("generic.rules.classic.name").tag(RulesType.Classic)
}
Image(systemName: "globe")
}
Section("newGame.dimensions") {
Stepper("newGame.dimensions.width \(width)", value: $width)
Stepper("newGame.dimensions.height \(height)", value: $height)
Stepper("newGame.dimensions.alignedTokens \(alignedTokens)", value: $alignedTokens)
}
Button("newGame.play") {
// TODO: yes
}
}
}
}
}
private struct PlayerSectionView: View {
@State private var type: PlayerType
@State private var name: String
@State private var photo: PhotosPickerItem? = nil
var body: some View {
Picker("newGame.player.type", selection: $type) {
Text("generic.player.type.human").tag(PlayerType.Human)
Text("generic.player.type.aiRandom").tag(PlayerType.AIRandom)
Text("generic.player.type.aiFinnishHim").tag(PlayerType.AIFinnishHim)
Text("generic.player.type.aiSimpleNegaMax").tag(PlayerType.AISimpleNegaMax)
}
let binding: Binding<String> = if (self.type == .Human) {
$name
} else {
// FIXME: make text field readonly
.constant("TODO constant name")
}
TextField("newGame.player.name", text: binding)
// TODO: MacOS
//.textInputSuggestions(isEnabled: true) {
//
//}
// TODO: actual photo support
Image(systemName: "globe").overlay {
PhotosPicker(selection: $photo) {
Text("newGame.player.photo.picker")
}
}
}
init(initialType type: PlayerType) {
self.type = type
self.name = "TODO default name"
}
}
private enum PlayerType {
case Human, AIRandom, AIFinnishHim, AISimpleNegaMax
}
private enum RulesType {
case Classic
}
#Preview {
NewGameView()
}
Loading…
Cancel
Save