AVALANCHE: Replace Nim::dogFood().

This commit is contained in:
uruk 2013-12-20 08:19:32 +01:00
parent 29c3f18d18
commit f9684f98f7
2 changed files with 87 additions and 85 deletions

View file

@ -286,90 +286,6 @@ void Nim::endOfGame() {
warning("STUB: Nim::endOfGame()");
}
void Nim::dogFood() {
_lmo = false;
byte live = 0;
byte sr[3];
for (int i = 0; i < 3; i++) {
if (_stones[i] > 0) {
_r[live] = i;
sr[live] = _stones[i];
live++;
}
}
switch (live) {
case 1: // Only one is free - so take 'em all!
_row = _r[0];
_number = _stones[_r[0]];
return;
case 2: // Two are free - make them equal!
if (sr[0] > sr[1]) { // T > b
_row = _r[0];
_number = sr[0] - sr[1];
} else if (sr[0] < sr[1]) { // B > t
_row = _r[1];
_number = sr[1] - sr[0];
} else { // B = t... oh no, we've lost!
_row = _r[0];
_number = 1;
}
return;
case 3: {
// Ho hum... this'll be difficult!
// There are three possible courses of action when we have 3 lines left:
// 1) Look for 2 equal lines, then take the odd one out.
// 2) Look for A.P.s, and capitalise on them.
// 3) Go any old where.
const byte other[3][2] = { { 2, 3 }, { 1, 3 }, { 1, 2 } };
for (int i = 0; i < 3; i++) { // Look for 2 equal lines.
if (_stones[other[i][0]] == _stones[other[i][1]]) {
_row = i; // This row.
_number = _stones[i]; // All of 'em.
return;
}
}
bool sorted;
do {
sorted = true;
for (int i = 0; i < 2; i++) {
if (sr[i] > sr[i + 1]) {
byte temp = sr[i + 1];
sr[i + 1] = sr[i];
sr[i] = temp;
temp = _r[i + 1];
_r[i + 1] = _r[i];
_r[i] = temp;
sorted = false;
}
}
} while (!sorted);
// Now we look for A.P.s...
for (int i = 0; i < 3; i++) {
findAp(i, 1); // There are 3 "1"s.
if (_lmo)
return; // Cut - out.
}
findAp(1, 2); // Only "2" possible.
if (_lmo)
return;
// A.P.search must have failed - use the default move.
_row = _r[2];
_number = 1;
return;
}
default:
break;
}
}
bool Nim::find(byte x) {
bool ret = false;
for (int i = 0; i < 3; i++) {
@ -429,4 +345,90 @@ void Nim::findAp(byte start, byte stepSize) {
}
}
void Nim::dogFood() {
_lmo = false;
byte live = 0;
byte sr[3];
for (int i = 0; i < 3; i++) {
if (_stones[i] > 0) {
_r[live] = i;
sr[live] = _stones[i];
live++;
}
}
switch (live) {
case 1: // Only one is free - so take 'em all!
_row = _r[0];
_number = _stones[_r[0]];
return;
case 2: // Two are free - make them equal!
if (sr[0] > sr[1]) { // T > b
_row = _r[0];
_number = sr[0] - sr[1];
}
else if (sr[0] < sr[1]) { // B > t
_row = _r[1];
_number = sr[1] - sr[0];
}
else { // B = t... oh no, we've lost!
_row = _r[0];
_number = 1;
}
return;
case 3: {
// Ho hum... this'll be difficult!
// There are three possible courses of action when we have 3 lines left:
// 1) Look for 2 equal lines, then take the odd one out.
// 2) Look for A.P.s, and capitalise on them.
// 3) Go any old where.
const byte other[3][2] = { { 2, 3 }, { 1, 3 }, { 1, 2 } };
for (int i = 0; i < 3; i++) { // Look for 2 equal lines.
if (_stones[other[i][0]] == _stones[other[i][1]]) {
_row = i; // This row.
_number = _stones[i]; // All of 'em.
return;
}
}
bool sorted;
do {
sorted = true;
for (int i = 0; i < 2; i++) {
if (sr[i] > sr[i + 1]) {
byte temp = sr[i + 1];
sr[i + 1] = sr[i];
sr[i] = temp;
temp = _r[i + 1];
_r[i + 1] = _r[i];
_r[i] = temp;
sorted = false;
}
}
} while (!sorted);
// Now we look for A.P.s...
for (int i = 0; i < 3; i++) {
findAp(i, 1); // There are 3 "1"s.
if (_lmo)
return; // Cut - out.
}
findAp(1, 2); // Only "2" possible.
if (_lmo)
return;
// A.P.search must have failed - use the default move.
_row = _r[2];
_number = 1;
return;
}
default:
break;
}
}
} // End of namespace Avalanche

View file

@ -69,9 +69,9 @@ private:
void less();
void takeSome();
void endOfGame();
void dogFood();
bool find(byte x); // This gives TRUE if there's a pile with x stones in.
void findAp(byte start, byte stepSize);
void dogFood();
};
} // End of namespace Avalanche