Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
C
COA-VANDEWAETER
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Fabio Vandewaeter
COA-VANDEWAETER
Commits
863433b8
Commit
863433b8
authored
2 months ago
by
Fabio Vandewaeter
Browse files
Options
Downloads
Patches
Plain Diff
readme
parent
b6892148
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
tp3/README.md
+233
-0
233 additions, 0 deletions
tp3/README.md
with
233 additions
and
0 deletions
tp3/README.md
+
233
−
0
View file @
863433b8
...
...
@@ -356,3 +356,236 @@ where
}
```
# 3. Long exercise proposal
```
rs
trait
Game
{
type
Move
;
type
Player
:
std
::
fmt
::
Debug
;
fn
current_player
(
&
self
)
->
Self
::
Player
;
fn
is_over
(
&
self
)
->
bool
;
fn
make_move
(
&
mut
self
,
mv
:
Self
::
Move
)
->
Result
<
(),
String
>
;
fn
display
(
&
self
);
fn
parse_move
(
input
:
&
str
)
->
Result
<
Self
::
Move
,
String
>
;
}
```
```
rs
#[derive(Clone,
Copy,
Debug,
PartialEq)]
enum
TicTacToePlayer
{
X
,
O
,
}
struct
TicTacToe
{
board
:
[
Option
<
TicTacToePlayer
>
;
9
],
current_player
:
TicTacToePlayer
,
}
impl
TicTacToe
{
fn
new
()
->
Self
{
Self
{
board
:
[
None
;
9
],
current_player
:
TicTacToePlayer
::
X
,
}
}
}
impl
Game
for
TicTacToe
{
type
Move
=
(
usize
,
usize
);
type
Player
=
TicTacToePlayer
;
fn
current_player
(
&
self
)
->
Self
::
Player
{
self
.current_player
}
fn
is_over
(
&
self
)
->
bool
{
let
b
=
&
self
.board
;
// Check rows.
for
i
in
0
..
3
{
if
let
Some
(
p
)
=
b
[
i
*
3
]
{
if
b
[
i
*
3
+
1
]
==
Some
(
p
)
&&
b
[
i
*
3
+
2
]
==
Some
(
p
)
{
return
true
;
}
}
}
// Check columns.
for
j
in
0
..
3
{
if
let
Some
(
p
)
=
b
[
j
]
{
if
b
[
j
+
3
]
==
Some
(
p
)
&&
b
[
j
+
6
]
==
Some
(
p
)
{
return
true
;
}
}
}
// Check diagonals.
if
let
Some
(
p
)
=
b
[
0
]
{
if
b
[
4
]
==
Some
(
p
)
&&
b
[
8
]
==
Some
(
p
)
{
return
true
;
}
}
if
let
Some
(
p
)
=
b
[
2
]
{
if
b
[
4
]
==
Some
(
p
)
&&
b
[
6
]
==
Some
(
p
)
{
return
true
;
}
}
// Game is over if board is full.
if
b
.iter
()
.all
(|
&
cell
|
cell
.is_some
())
{
return
true
;
}
false
}
fn
make_move
(
&
mut
self
,
mv
:
Self
::
Move
)
->
Result
<
(),
String
>
{
let
(
row
,
col
)
=
mv
;
if
row
>=
3
||
col
>=
3
{
return
Err
(
"Move out of bounds"
.to_string
());
}
let
idx
=
row
*
3
+
col
;
if
self
.board
[
idx
]
.is_some
()
{
return
Err
(
"Cell already occupied"
.to_string
());
}
self
.board
[
idx
]
=
Some
(
self
.current_player
);
// Switch player.
self
.current_player
=
match
self
.current_player
{
TicTacToePlayer
::
X
=>
TicTacToePlayer
::
O
,
TicTacToePlayer
::
O
=>
TicTacToePlayer
::
X
,
};
Ok
(())
}
fn
display
(
&
self
)
{
println!
(
"Current board:"
);
for
row
in
0
..
3
{
for
col
in
0
..
3
{
let
idx
=
row
*
3
+
col
;
let
symbol
=
match
self
.board
[
idx
]
{
Some
(
TicTacToePlayer
::
X
)
=>
"X"
,
Some
(
TicTacToePlayer
::
O
)
=>
"O"
,
None
=>
"."
,
};
print!
(
"{} "
,
symbol
);
}
println!
();
}
}
fn
parse_move
(
input
:
&
str
)
->
Result
<
Self
::
Move
,
String
>
{
// Expect two numbers separated by whitespace (e.g., "0 1")
let
parts
:
Vec
<&
str
>
=
input
.split_whitespace
()
.collect
();
if
parts
.len
()
!=
2
{
return
Err
(
"Please enter two numbers separated by space"
.to_string
());
}
let
row
=
parts
[
0
]
.parse
::
<
usize
>
()
.map_err
(|
_
|
"Invalid row"
.to_string
())
?
;
let
col
=
parts
[
1
]
.parse
::
<
usize
>
()
.map_err
(|
_
|
"Invalid column"
.to_string
())
?
;
Ok
((
row
,
col
))
}
}
```
```
rs
#[derive(Clone,
Copy,
Debug,
PartialEq)]
enum
NimGamePlayer
{
First
,
Second
,
}
struct
NimGame
{
stones
:
u32
,
current_player
:
NimGamePlayer
,
}
impl
NimGame
{
fn
new
(
stones
:
u32
)
->
Self
{
Self
{
stones
:
stones
,
current_player
:
NimGamePlayer
::
First
,
}
}
}
impl
Game
for
NimGame
{
type
Move
=
u32
;
type
Player
=
NimGamePlayer
;
fn
current_player
(
&
self
)
->
Self
::
Player
{
self
.current_player
}
fn
is_over
(
&
self
)
->
bool
{
self
.stones
==
0
}
fn
make_move
(
&
mut
self
,
mv
:
Self
::
Move
)
->
Result
<
(),
String
>
{
if
mv
<
1
||
mv
>
2
{
return
Err
(
"You can only remove 1 or 2 stones"
.to_string
());
}
if
mv
>
self
.stones
{
return
Err
(
"Not enough stones remaining"
.to_string
());
}
self
.stones
-=
mv
;
self
.current_player
=
match
self
.current_player
{
NimGamePlayer
::
First
=>
NimGamePlayer
::
Second
,
NimGamePlayer
::
Second
=>
NimGamePlayer
::
First
,
};
Ok
(())
}
fn
display
(
&
self
)
{
println!
(
"Stones remaining: {}"
,
self
.stones
);
}
fn
parse_move
(
input
:
&
str
)
->
Result
<
Self
::
Move
,
String
>
{
input
.trim
()
.parse
::
<
u32
>
()
.map_err
(|
_
|
"Invalid number"
.to_string
())
}
}
```
```
rs
fn
play_game
<
G
:
Game
>
(
mut
game
:
G
)
{
while
!
game
.is_over
()
{
game
.display
();
print!
(
"Player {:?}, enter your move: "
,
game
.current_player
());
std
::
io
::
stdout
()
.flush
()
.unwrap
();
let
mut
input
=
String
::
new
();
std
::
io
::
stdin
()
.read_line
(
&
mut
input
)
.expect
(
"Failed to read input"
);
match
G
::
parse_move
(
input
.trim
())
{
Ok
(
mv
)
=>
{
if
let
Err
(
e
)
=
game
.make_move
(
mv
)
{
println!
(
"Error: {}"
,
e
);
}
}
Err
(
e
)
=>
println!
(
"Invalid move: {}"
,
e
),
}
}
println!
(
"Game over!"
);
game
.display
();
}
```
```
rs
fn
main
()
{
println!
(
"
\n
--- Game engine demo ---"
);
let
mut
choice
=
String
::
new
();
println!
(
"
\n
--- Select game ---"
);
println!
(
"1: Tic Tac Toe"
);
println!
(
"2: Nim Game"
);
let
mut
game_choice
=
String
::
new
();
std
::
io
::
stdin
()
.read_line
(
&
mut
game_choice
)
.unwrap
();
match
game_choice
.trim
()
{
"1"
=>
{
let
game
=
TicTacToe
::
new
();
play_game
(
game
);
}
"2"
=>
{
println!
(
"Enter initial number of stones:"
);
let
mut
stones_str
=
String
::
new
();
std
::
io
::
stdin
()
.read_line
(
&
mut
stones_str
)
.unwrap
();
let
stones
=
stones_str
.trim
()
.parse
::
<
u32
>
()
.unwrap_or
(
10
);
let
game
=
NimGame
::
new
(
stones
);
play_game
(
game
);
}
_
=>
println!
(
"Invalid game choice"
),
}
}
```
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment