From 0f70fa0a1be9a90e6646639d36eb2185d28546e4 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Sat, 23 Oct 2021 01:36:01 +0300 Subject: [PATCH] GROOVIE: Split the gallery puzzle logic into a separate file --- engines/groovie/logic/gallery.cpp | 185 ++++++++++++++++++++++++++ engines/groovie/logic/gallery.h | 87 +++++++++++++ engines/groovie/logic/t11hgame.cpp | 202 +---------------------------- engines/groovie/logic/t11hgame.h | 4 +- engines/groovie/module.mk | 1 + 5 files changed, 276 insertions(+), 203 deletions(-) create mode 100644 engines/groovie/logic/gallery.cpp create mode 100644 engines/groovie/logic/gallery.h diff --git a/engines/groovie/logic/gallery.cpp b/engines/groovie/logic/gallery.cpp new file mode 100644 index 00000000000..6ae6c4a4e63 --- /dev/null +++ b/engines/groovie/logic/gallery.cpp @@ -0,0 +1,185 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "groovie/groovie.h" +#include "groovie/logic/gallery.h" + +namespace Groovie { + +// Links between the pieces in the Gallery challenge +// For example, the first row signifies that piece 1 +// is connected to pieces 2, 4 and 5 +const byte GalleryGame::kGalleryLinks[21][10] = { + { 2, 4, 5, 0, 0, 0, 0, 0, 0, 0 }, // 1 + { 1, 5, 3, 0, 0, 0, 0, 0, 0, 0 }, // 2 + { 2, 5, 9, 12, 0, 0, 0, 0, 0, 0 }, // 3 + { 1, 5, 6, 7, 8, 0, 0, 0, 0, 0 }, // 4 + { 1, 2, 3, 4, 7, 8, 9, 0, 0, 0 }, // 5 + { 4, 7, 10, 11, 13, 14, 15, 16, 18, 0 }, // 6 + { 4, 5, 6, 8, 9, 10, 0, 0, 0, 0 }, // 7 + { 4, 5, 7, 0, 0, 0, 0, 0, 0, 0 }, // 8 + { 3, 5, 7, 10, 11, 12, 18, 0, 0, 0 }, // 9 + { 6, 7, 9, 11, 0, 0, 0, 0, 0, 0 }, // 10 + { 6, 9, 10, 18, 0, 0, 0, 0, 0, 0 }, // 11 + { 3, 9, 18, 21, 0, 0, 0, 0, 0, 0 }, // 12 + { 6, 14, 17, 19, 0, 0, 0, 0, 0, 0 }, // 13 + { 6, 13, 15, 17, 19, 20, 21, 0, 0, 0 }, // 14 + { 6, 14, 16, 18, 21, 0, 0, 0, 0, 0 }, // 15 + { 6, 15, 0, 0, 0, 0, 0, 0, 0, 0 }, // 16 + {13, 14, 19, 0, 0, 0, 0, 0, 0, 0 }, // 17 + { 6, 9, 11, 12, 15, 21, 0, 0, 0, 0 }, // 18 + {13, 14, 17, 20, 0, 0, 0, 0, 0, 0 }, // 19 + {14, 19, 21, 0, 0, 0, 0, 0, 0, 0 }, // 20 + {12, 14, 15, 18, 20, 0, 0, 0, 0, 0 } // 21 +}; + +const int kPieceCount = 21; +enum kGalleryPieceStatus { + kPieceUnselected = 0, + kPieceSelected = 1 +}; + +void GalleryGame::run(byte *scriptVariables) { + byte pieceStatus[kPieceCount]; + byte status1[kPieceCount]; + byte status2[kPieceCount]; + + memcpy(pieceStatus, scriptVariables + 26, kPieceCount); + + int selectedPieces = 0; + for (int i = 0; i < kPieceCount; i++) { + status1[i] = 0; + if (pieceStatus[i] == kPieceSelected) { + for (int j = 0; j < kPieceCount; j++) + status2[j] = pieceStatus[j]; + + byte curLink = kGalleryLinks[i][0]; + pieceStatus[i] = kPieceUnselected; + status2[i] = 0; + + int linkedPiece = 1; + while (curLink != 0) { + linkedPiece++; + status2[curLink - 1] = kPieceUnselected; + curLink = kGalleryLinks[i][linkedPiece - 1]; + } + status1[i] = galleryAI(status2, 1); + if (status1[i] == kPieceSelected) { + selectedPieces++; + } + } + } + + if (selectedPieces == 0) { + int esi = 0; + for (int i = 0; i < kPieceCount; i++) { + if (esi < status1[i]) { + esi = status1[i]; + } + } + + if (esi == 2) { + esi = 1; + } else { + if (esi < kPieceCount) { + esi = 2; + } else { + esi -= 12; + } + } + + for (int i = 0; i < kPieceCount; i++) { + if (esi < status1[i]) { + status1[i] = kPieceSelected; + selectedPieces++; + } + } + } + + int selectedPiece = 0; + + byte v12 = scriptVariables[49] % selectedPieces; + for (int i = 0; i < kPieceCount; i++) { + if (status1[selectedPiece] == 1 && !v12--) + break; + + selectedPiece++; + } + + scriptVariables[47] = (selectedPiece + 1) / 10; + scriptVariables[48] = (selectedPiece + 1) % 10; +} + +byte GalleryGame::galleryAI(byte *pieceStatus, int depth) { + byte status1[kPieceCount]; + byte status2[kPieceCount]; + + int selectedPieces = 0; + + for (int i = 0; i < kPieceCount; i++) { + status1[i] = 0; + if (pieceStatus[i] == kPieceSelected) { + for (int j = 0; j < kPieceCount; j++) + status2[j] = pieceStatus[j]; + + byte curLink = kGalleryLinks[i][0]; + pieceStatus[i] = kPieceUnselected; + status2[i] = 0; + selectedPieces = 1; + + int linkedPiece = 1; + while (curLink != 0) { + linkedPiece++; + status2[curLink - 1] = kPieceUnselected; + curLink = kGalleryLinks[i][linkedPiece - 1]; + } + status1[i] = galleryAI(status2, depth == 0 ? 1 : 0); + if (!depth && status1[i] == kPieceSelected) { + return 1; + } + } + } + + if (selectedPieces) { + byte v8 = 0; + byte v9 = 0; + byte v10 = 0; + for (int j = 0; j < 21; ++j) { + byte v12 = status2[j]; + if (v12) { + ++v10; + if (v12 == 1) + ++v9; + else + v8 += v12; + } + } + if (v9 == v10) + return 1; + else + return (v8 + 102 * v9) / v10; + } + + return depth == 0 ? 2 : 1; +} + +} // End of Groovie namespace diff --git a/engines/groovie/logic/gallery.h b/engines/groovie/logic/gallery.h new file mode 100644 index 00000000000..f86f0b184c6 --- /dev/null +++ b/engines/groovie/logic/gallery.h @@ -0,0 +1,87 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef GROOVIE_LOGIC_GALLERY_H +#define GROOVIE_LOGIC_GALLERY_H + +#include "common/random.h" +#include "common/system.h" + +namespace Groovie { + +/* + * Puzzle in the Gallery. + * The aim is to select the last piece of the image. + * There are 18 pieces in total. + * When selecting a piece, all surrounding pieces are also selected + * + * +--------------------+--------------------------------+--------+ + * | 1/1A | 2/1B | | + * | +--------------+--+--------------------------+-----+ | + * | | | | | + * +--+ 4/1D | 5/1E | 3/1C | + * | | | | + * +-----+--------+--+--------+-----------------+--+--------+ | + * | | | | | | | + * | | | | | | | + * | | | 8/21 | | | | + * | | | | +-----------+ | | + * | | | | | | | | + * | | +-----------+ | 10/23 | 9/22 | | + * | | | | | | + * | | 7/20 +-----+-----+ +-----+ + * | | | | | | | + * | +--------------------------+ | | | | + * | 6/1F | | | | + * +-----------+-----------+-----+--+ | 11 | | 12 | + * | 13/26 | | | | | / | | / | + * | +-----+-----+ | | | | 24 +-----------+ 25 | + * | | | | | | | | | | + * +-----+ 17/2A | | |16| | | | | + * | | | | |/ | | | | | + * | +-----+-----+ | |29| | | +-----+ + * | | | | | | | | | + * | | | | | +-----+ 18/2B | | + * | 19/2C | 14/27 | | | | | | + * | | | | +-----------+ | | + * | | | | | | | | + * | | | +--+ 15/28 | | | + * | | | | | | + * | +--------+--+--------------------+-----------+ | + * | | 20/2D | 21/2E | + * +-----------+--------+-----------------------------------------+ + */ + +class GalleryGame { +public: + GalleryGame() {} + void run(byte *scriptVariables); + +private: + byte galleryAI(byte *pieceStatus, int depth); + + static const byte kGalleryLinks[21][10]; +}; + +} // End of Groovie namespace + +#endif // GROOVIE_LOGIC_GALLERY_H diff --git a/engines/groovie/logic/t11hgame.cpp b/engines/groovie/logic/t11hgame.cpp index 8a3b332a6a5..f6d79aeac89 100644 --- a/engines/groovie/logic/t11hgame.cpp +++ b/engines/groovie/logic/t11hgame.cpp @@ -56,7 +56,7 @@ void T11hGame::handleOp(uint8 op) { case 3: debugC(1, kDebugScript, "Groovie::Script Op42 (0x%02X): T11H Make last move on modern art picture in the gallery (bs.grv)", op); - opGallery(); + _gallery.run(_scriptVariables); break; case 4: @@ -182,206 +182,6 @@ void T11hGame::opPente() { _scriptVariables[5] = 4; } -/* - * Puzzle in the Gallery. - * The aim is to select the last piece of the image. - * There are 18 pieces in total. - * When selecting a piece, all surrounding pieces are also selected - * - * +--------------------+--------------------------------+--------+ - * | 1/1A | 2/1B | | - * | +--------------+--+--------------------------+-----+ | - * | | | | | - * +--+ 4/1D | 5/1E | 3/1C | - * | | | | - * +-----+--------+--+--------+-----------------+--+--------+ | - * | | | | | | | - * | | | | | | | - * | | | 8/21 | | | | - * | | | | +-----------+ | | - * | | | | | | | | - * | | +-----------+ | 10/23 | 9/22 | | - * | | | | | | - * | | 7/20 +-----+-----+ +-----+ - * | | | | | | | - * | +--------------------------+ | | | | - * | 6/1F | | | | - * +-----------+-----------+-----+--+ | 11 | | 12 | - * | 13/26 | | | | | / | | / | - * | +-----+-----+ | | | | 24 +-----------+ 25 | - * | | | | | | | | | | - * +-----+ 17/2A | | |16| | | | | - * | | | | |/ | | | | | - * | +-----+-----+ | |29| | | +-----+ - * | | | | | | | | | - * | | | | | +-----+ 18/2B | | - * | 19/2C | 14/27 | | | | | | - * | | | | +-----------+ | | - * | | | | | | | | - * | | | +--+ 15/28 | | | - * | | | | | | - * | +--------+--+--------------------+-----------+ | - * | | 20/2D | 21/2E | - * +-----------+--------+-----------------------------------------+ - */ - -// Links between the pieces in the Gallery challenge -// For example, the first row signifies that piece 1 -// is connected to pieces 2, 4 and 5 -const byte T11hGame::kGalleryLinks[21][10] = { - { 2, 4, 5, 0, 0, 0, 0, 0, 0, 0 }, // 1 - { 1, 5, 3, 0, 0, 0, 0, 0, 0, 0 }, // 2 - { 2, 5, 9, 12, 0, 0, 0, 0, 0, 0 }, // 3 - { 1, 5, 6, 7, 8, 0, 0, 0, 0, 0 }, // 4 - { 1, 2, 3, 4, 7, 8, 9, 0, 0, 0 }, // 5 - { 4, 7, 10, 11, 13, 14, 15, 16, 18, 0 }, // 6 - { 4, 5, 6, 8, 9, 10, 0, 0, 0, 0 }, // 7 - { 4, 5, 7, 0, 0, 0, 0, 0, 0, 0 }, // 8 - { 3, 5, 7, 10, 11, 12, 18, 0, 0, 0 }, // 9 - { 6, 7, 9, 11, 0, 0, 0, 0, 0, 0 }, // 10 - { 6, 9, 10, 18, 0, 0, 0, 0, 0, 0 }, // 11 - { 3, 9, 18, 21, 0, 0, 0, 0, 0, 0 }, // 12 - { 6, 14, 17, 19, 0, 0, 0, 0, 0, 0 }, // 13 - { 6, 13, 15, 17, 19, 20, 21, 0, 0, 0 }, // 14 - { 6, 14, 16, 18, 21, 0, 0, 0, 0, 0 }, // 15 - { 6, 15, 0, 0, 0, 0, 0, 0, 0, 0 }, // 16 - {13, 14, 19, 0, 0, 0, 0, 0, 0, 0 }, // 17 - { 6, 9, 11, 12, 15, 21, 0, 0, 0, 0 }, // 18 - {13, 14, 17, 20, 0, 0, 0, 0, 0, 0 }, // 19 - {14, 19, 21, 0, 0, 0, 0, 0, 0, 0 }, // 20 - {12, 14, 15, 18, 20, 0, 0, 0, 0, 0 } // 21 -}; - -const int kPieceCount = 21; -enum kGalleryPieceStatus { - kPieceUnselected = 0, - kPieceSelected = 1 -}; - -void T11hGame::opGallery() { - byte pieceStatus[kPieceCount]; - byte status1[kPieceCount]; - byte status2[kPieceCount]; - - memcpy(pieceStatus, _scriptVariables + 26, kPieceCount); - - int selectedPieces = 0; - for (int i = 0; i < kPieceCount; i++) { - status1[i] = 0; - if (pieceStatus[i] == kPieceSelected) { - for (int j = 0; j < kPieceCount; j++) - status2[j] = pieceStatus[j]; - - byte curLink = kGalleryLinks[i][0]; - pieceStatus[i] = kPieceUnselected; - status2[i] = 0; - - int linkedPiece = 1; - while (curLink != 0) { - linkedPiece++; - status2[curLink - 1] = kPieceUnselected; - curLink = kGalleryLinks[i][linkedPiece - 1]; - } - status1[i] = opGalleryAI(status2, 1); - if (status1[i] == kPieceSelected) { - selectedPieces++; - } - } - } - - if (selectedPieces == 0) { - int esi = 0; - for (int i = 0; i < kPieceCount; i++) { - if (esi < status1[i]) { - esi = status1[i]; - } - } - - if (esi == 2) { - esi = 1; - } else { - if (esi < kPieceCount) { - esi = 2; - } else { - esi -= 12; - } - } - - for (int i = 0; i < kPieceCount; i++) { - if (esi < status1[i]) { - status1[i] = kPieceSelected; - selectedPieces++; - } - } - } - - int selectedPiece = 0; - - byte v12 = _scriptVariables[49] % selectedPieces; - for (int i = 0; i < kPieceCount; i++) { - if (status1[selectedPiece] == 1 && !v12--) - break; - - selectedPiece++; - } - - _scriptVariables[47] = (selectedPiece + 1) / 10; - _scriptVariables[48] = (selectedPiece + 1) % 10; -} - -byte T11hGame::opGalleryAI(byte *pieceStatus, int depth) { - byte status1[kPieceCount]; - byte status2[kPieceCount]; - - int selectedPieces = 0; - - for (int i = 0; i < kPieceCount; i++) { - status1[i] = 0; - if (pieceStatus[i] == kPieceSelected) { - for (int j = 0; j < kPieceCount; j++) - status2[j] = pieceStatus[j]; - - byte curLink = kGalleryLinks[i][0]; - pieceStatus[i] = kPieceUnselected; - status2[i] = 0; - selectedPieces = 1; - - int linkedPiece = 1; - while (curLink != 0) { - linkedPiece++; - status2[curLink - 1] = kPieceUnselected; - curLink = kGalleryLinks[i][linkedPiece - 1]; - } - status1[i] = opGalleryAI(status2, depth == 0 ? 1 : 0); - if (!depth && status1[i] == kPieceSelected) { - return 1; - } - } - } - - if (selectedPieces) { - byte v8 = 0; - byte v9 = 0; - byte v10 = 0; - for (int j = 0; j < 21; ++j) { - byte v12 = status2[j]; - if (v12) { - ++v10; - if (v12 == 1) - ++v9; - else - v8 += v12; - } - } - if (v9 == v10) - return 1; - else - return (v8 + 102 * v9) / v10; - } - - return depth == 0 ? 2 : 1; -} - void T11hGame::opTriangle() { // TODO } diff --git a/engines/groovie/logic/t11hgame.h b/engines/groovie/logic/t11hgame.h index 068c965a1d6..c78cee7b5b1 100644 --- a/engines/groovie/logic/t11hgame.h +++ b/engines/groovie/logic/t11hgame.h @@ -26,6 +26,7 @@ #include "common/textconsole.h" #include "common/random.h" #include "groovie/logic/beehive.h" +#include "groovie/logic/gallery.h" namespace Groovie { @@ -60,8 +61,7 @@ private: byte *_scriptVariables; BeehiveGame _beehive; - - static const byte kGalleryLinks[21][10]; + GalleryGame _gallery; #endif }; diff --git a/engines/groovie/module.mk b/engines/groovie/module.mk index 556d5a8b30e..94c59f99034 100644 --- a/engines/groovie/module.mk +++ b/engines/groovie/module.mk @@ -21,6 +21,7 @@ MODULE_OBJS += \ logic/beehive.o \ logic/cake.o \ logic/clangame.o \ + logic/gallery.o \ logic/t11hgame.o \ logic/tlcgame.o \ video/roq.o