Skip to content

Instantly share code, notes, and snippets.

@ali2236
Last active June 28, 2021 16:12
Show Gist options
  • Save ali2236/a2c7d1d325c61bf06df68c85235d8ae9 to your computer and use it in GitHub Desktop.
Save ali2236/a2c7d1d325c61bf06df68c85235d8ae9 to your computer and use it in GitHub Desktop.
AI homework #3
/*
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