Last active
June 28, 2021 16:12
-
-
Save ali2236/a2c7d1d325c61bf06df68c85235d8ae9 to your computer and use it in GitHub Desktop.
AI homework #3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Ali Ghanbari - 970216657 | |
online compiler: https://dartpad.dev/a2c7d1d325c61bf06df68c85235d8ae9?null_safety=true | |
*/ | |
const n = 3; | |
enum Position { Left, Right } | |
enum Move { MM, M, MC, C, CC, None } | |
void main() { | |
var startingState = new State(3, 3, Position.Right); | |
print('M-Left\tC-Left\tBoat\tM-Right\tC-Right'); | |
print(startingState.row); | |
final goal = recursiveDLS(startingState, 12); | |
print(goal?.row); | |
print(''); | |
print(goal?.steps.map((e) => e.toString() + '\n').toList()); | |
} | |
State? recursiveDLS(State state, [int limit = 20]) { | |
if (goal(state)) return state; | |
if (limit == 0) return null; | |
return state.successors | |
.where(valid) | |
.map((successor) => recursiveDLS(successor, limit - 1)) | |
.firstWhere(goal, orElse: () => null); | |
} | |
class Step { | |
final Move move; | |
final Position position; | |
const Step(this.move, this.position); | |
@override | |
String toString() => '($move, $position)'; | |
} | |
// start right | |
// end left | |
class State { | |
final int missionariesRight; | |
final int cannibalsRight; | |
final Position boat; | |
final List<Step> steps; | |
State( | |
this.missionariesRight, | |
this.cannibalsRight, | |
this.boat, [ | |
Move move = Move.None, | |
List<Step> parentSteps = const [], | |
]) : steps = [...parentSteps, Step(move, boat)]; | |
int get missionariesLeft => n - missionariesRight; | |
int get cannibalsLeft => n - cannibalsRight; | |
Iterable<State> get successors sync* { | |
if (boat == Position.Left) { | |
yield State(missionariesRight + 2, cannibalsRight, Position.Right, | |
Move.MM, steps); | |
yield State( | |
missionariesRight + 1, cannibalsRight, Position.Right, Move.M, steps); | |
yield State(missionariesRight + 1, cannibalsRight + 1, Position.Right, | |
Move.MC, steps); | |
yield State( | |
missionariesRight, cannibalsRight + 1, Position.Right, Move.C, steps); | |
yield State(missionariesRight, cannibalsRight + 2, Position.Right, | |
Move.CC, steps); | |
} else { | |
yield State( | |
missionariesRight - 2, cannibalsRight, Position.Left, Move.MM, steps); | |
yield State( | |
missionariesRight - 1, cannibalsRight, Position.Left, Move.M, steps); | |
yield State(missionariesRight - 1, cannibalsRight - 1, Position.Left, | |
Move.MC, steps); | |
yield State( | |
missionariesRight, cannibalsRight - 1, Position.Left, Move.C, steps); | |
yield State( | |
missionariesRight, cannibalsRight - 2, Position.Left, Move.CC, steps); | |
} | |
} | |
@override | |
String toString() { | |
return "($missionariesRight, $cannibalsRight, $boat)"; | |
} | |
String get row => | |
'$missionariesLeft\t$cannibalsLeft\t${boat.index == 0 ? 'Left' : 'Right'}\t$missionariesRight\t$cannibalsRight'; | |
} | |
bool goal(State? s) => | |
s != null ? s.missionariesRight == 0 && s.cannibalsRight == 0 : false; | |
bool valid(State s) => | |
s.missionariesRight >= 0 && | |
s.cannibalsRight >= 0 && | |
s.missionariesRight <= n && | |
s.cannibalsRight <= n && | |
(s.missionariesRight == 0 || s.missionariesRight >= s.cannibalsRight) && | |
(s.missionariesLeft == 0 || s.missionariesLeft >= s.cannibalsLeft); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment