 Those who read my series of articles devoted to Zillions of Games might have the impression that I was completely satisfied with this product. Of course, it is not. ZoG is unique in that it allows you to quickly and practically “on the knee” to develop a prototype of almost any logical game, but this does not mean that it is perfect. Today, I want to talk about what I do not like about this project.
 Those who read my series of articles devoted to Zillions of Games might have the impression that I was completely satisfied with this product. Of course, it is not. ZoG is unique in that it allows you to quickly and practically “on the knee” to develop a prototype of almost any logical game, but this does not mean that it is perfect. Today, I want to talk about what I do not like about this project. Compared to the variety of all sorts of rules, which I described in the previous article , the concept of Chess looks very simple. In part, this illusion is supported by the fact that, most of us, are familiar with Chess from early childhood. Of course, this simplicity is deceptive! And the point here is not even in the exotic rules of " taking on the aisle " and castling (because of which the cascade and set-attribute commands had to be added to ZRF). I propose to deal with a deeper question underlying the game itself. What should the King do under the check?
 Compared to the variety of all sorts of rules, which I described in the previous article , the concept of Chess looks very simple. In part, this illusion is supported by the fact that, most of us, are familiar with Chess from early childhood. Of course, this simplicity is deceptive! And the point here is not even in the exotic rules of " taking on the aisle " and castling (because of which the cascade and set-attribute commands had to be added to ZRF). I propose to deal with a deeper question underlying the game itself. What should the King do under the check?(loss-condition (White Black) (checkmated King))  With Checkers, everything is also not at all smooth. The main difference from Chess is the obligatory take and the possibility of a series of takes. To implement these rules, partial moves ( add-partial ) and move priorities ( move-priorities ) are introduced in ZRF. The mechanism of priorities is not very convenient to use, but it works. A player will not be able to make a non-priority move if he has the possibility of a priority move But this is not the end! In some types of Checkers (for example, in international 100-cell Checkers), from all possible moves with a take, the player must choose the option of taking the maximum number of pieces (in this case, ladies can be taken into account or not taken into account).
 With Checkers, everything is also not at all smooth. The main difference from Chess is the obligatory take and the possibility of a series of takes. To implement these rules, partial moves ( add-partial ) and move priorities ( move-priorities ) are introduced in ZRF. The mechanism of priorities is not very convenient to use, but it works. A player will not be able to make a non-priority move if he has the possibility of a priority move But this is not the end! In some types of Checkers (for example, in international 100-cell Checkers), from all possible moves with a take, the player must choose the option of taking the maximum number of pieces (in this case, ladies can be taken into account or not taken into account). (option "maximal captures" true)  (option "maximal captures" 2)  (win-condition (XO) (or (relative-config man n man n man) (relative-config man e man e man) (relative-config man ne man ne man) (relative-config man nw man nw man) )  (define Check-for-3 (set-flag first? false) (set-flag second? false) (set-flag third? false) (set-flag fourth? false) a1 (while (and (on-board? next)(not-flag? fourth?)) (if friend? (if (not-flag? first?) (set-flag first? true) else (if (not-flag? second?) (set-flag second? true) else (if (not-flag? third?) (set-flag third? true) else (set-flag fourth? true) ) ) ) ) next ) (verify (not-flag? fourth?)) (if (am-Black?) (change-type Jumping z0) ;set permanent flag else (change-type Jumping z1) ;set permanent flag ) )  Another disadvantage of ZRF is the complete lack of any arithmetic operations in it. It's not scary, as long as we restrict ourselves to Chess and Checkers, but there are games in which the execution of arithmetic operations is necessary when calculating the turn! Of course, I'm talking about ritmomachia . This medieval game is not particularly popular in our time, but it definitely challenges the versatility of the game engine. Here are the conditions under which the figures can be fought in this game:
 Another disadvantage of ZRF is the complete lack of any arithmetic operations in it. It's not scary, as long as we restrict ourselves to Chess and Checkers, but there are games in which the execution of arithmetic operations is necessary when calculating the turn! Of course, I'm talking about ritmomachia . This medieval game is not particularly popular in our time, but it definitely challenges the versatility of the game engine. Here are the conditions under which the figures can be fought in this game: // Engine.h // // Copyright 1998-2000 Zillions Development // // Header file for plug-in DLL engine to Zillions #include "EngineDLL.h" DLL_Result FAR PASCAL DLL_Search(long lSearchTime, long lDepthLimit, long lVariety, Search_Status *pSearchStatus, LPSTR bestMove, LPSTR currentMove, long *plNodes, long *plScore, long *plDepth); DLL_Result FAR PASCAL DLL_MakeAMove(LPCSTR move); DLL_Result FAR PASCAL DLL_StartNewGame(LPCSTR variant); DLL_Result FAR PASCAL DLL_CleanUp(); DLL_Result FAR PASCAL DLL_IsGameOver(long *lResult, LPSTR zcomment); DLL_Result FAR PASCAL DLL_GenerateMoves(LPCSTR moveBuffer);  // EngineDLL.h // // Copyright 1998-2000 Zillions Development // // Shared DLL plug-in for DLL engine and Zillions #include "windows.h" typedef enum { kKEEPSEARCHING = 0, kSTOPSOON = 1, kSTOPNOW = 2 } Search_Status; typedef enum { DLL_OK = 0, DLL_OK_DONT_SEND_SETUP = 1, // only supported in 1.0.2 and higher! DLL_GENERIC_ERROR = -1, DLL_OUT_OF_MEMORY_ERROR = -2, DLL_UNKNOWN_VARIANT_ERROR = -3, DLL_UNKNOWN_PLAYER_ERROR = -4, DLL_UNKNOWN_PIECE_ERROR = -5, DLL_WRONG_SIDE_TO_MOVE_ERROR = -6, DLL_INVALID_POSITION_ERROR = -7, DLL_NO_MOVES = -8 } DLL_Result; enum { UNKNOWN_SCORE = -2140000000L, LOSS_SCORE = -2130000000L, DRAW_SCORE = 0, WIN_SCORE = 2130000000L }; // ***** REQUIRED ROUTINES // DLL_Search // // The DLL should search from the current position. If it returns DLL_OK it should // also return the best move found in str; however, it should not make the move // internally. A separate call to MakeAMove() will follow to make the move the // engine returns. // // -> lSearchTime: Target search time in milliseconds // -> lDepthLimit: Maximum moves deep the engine should search // -> lVariety: Variety setting for engine. 0 = no variety, 10 = most variety // -> pSearchStatus: Pointer to variable where Zillions will report search status // -> bestMove: Pointer to a string where engine can report the best move found so far // -> currentMove: Pointer to a string where engine can report the move being searched // -> plNodes: Pointer to a long where engine can report # of positions searched so far // -> plScore: Pointer to a long where engine can report current best score in search // -> plDepth: Pointer to a long where engine can report current search depth // // Returns DLL_OK or a negative error code typedef DLL_Result (FAR PASCAL *SEARCH)(long lSearchTime, long lDepthLimit, long lVariety, const Search_Status *pSearchStatus, LPSTR bestMove, LPSTR currentMove, long *plNodes, long *plScore, long *plDepth); // DLL_MakeAMove // // The DLL should try to make the given move internally. // // -> move: notation for the move that the engine should make // // Returns DLL_OK or a negative error code typedef DLL_Result (FAR PASCAL *MAKEAMOVE)(LPCSTR move); // DLL_StartNewGame // // The DLL should reset the board for a new game. // // -> variant: The variant to be played as it appears in the variant menu // // Returns DLL_OK, DLL_OK_DONT_SEND_SETUP, DLL_OUT_OF_MEMORY_ERROR, or // DLL_GENERIC_ERROR typedef DLL_Result (FAR PASCAL *STARTNEWGAME)(LPCSTR variant); // DLL_CleanUp // // The DLL should free memory and prepare to be unloaded. // // Returns DLL_OK, DLL_OUT_OF_MEMORY_ERROR, or DLL_GENERIC_ERROR typedef DLL_Result (FAR PASCAL *CLEANUP)(void); // ***** OPTIONAL ROUTINES // DLL_IsGameOver // // This optional function is called by Zillions to see if a game is over. If // not present, Zillions uses the goal in the ZRF to decide the winner. // // -> lResult: Pointer to the game result which the DLL should fill in when // called. If the game is over the routine should fill in WIN_SCORE, // DRAW_SCORE, or LOSS_SCORE. Otherwise the routine should fill in // UNKNOWN_SCORE. // -> zcomment: Pointer to a 500-char string in Zillions which the DLL can optionally // fill in, to make an announcement about why the game is over, such // as "Draw by third repetition". The DLL should not modify this // string if there is nothing to report. // // Returns DLL_OK or a negative error code typedef DLL_Result (FAR PASCAL *ISGAMEOVER)(long *lResult, LPSTR zcomment); // DLL_GenerateMoves // // You can use GenerateMoves in your DLL to tell Zillions the legal moves for // any position in the game. // // -> moveBuffer: Pointer to a 1024-char sting which the DLL should fill in when // called. Initial call should be with moveBuffer set to "". Each call // to GenerateMoves should fill in the next available move from the // current position, with a final "" when no more moves are available. // All moves must be in valid Zillions move string format. // // Returns DLL_OK or a negative error code typedef DLL_Result (FAR PASCAL *GENERATEMOVES)(LPCSTR moveBuffer);  Continuing my story about the shortcomings of ZRF, I just can not get past the games with incomplete information . There are implementations of such games on ZRF, but are they fair? They just hide some of the information from the person . AI perfectly sees all the figures! You must agree that such a “one gate” game has little in common with the fact that all players have incomplete information. Apparently, this is one of the reasons why so few card games are implemented for ZoG. Not very interesting to play with someone who knows all your cards. There is another side to this question. I have already mentioned Battle vs Chess more than once. Most of the missions in the campaigns of this game are based on the fact that people and computers play according to different rules. For example, in the “Point of no return” mission it is required to lure the enemy's pieces to the mines located on the field. But if the AI ​​knows the location of the mines, it simply will not go to these fields! What is the point of making a move, as a result of which you simply lose a piece? In order for the game to proceed as it was intended by the developers, the computer must “think” that it plays by the usual rules. This is also a variant of the game with incomplete information.
 Continuing my story about the shortcomings of ZRF, I just can not get past the games with incomplete information . There are implementations of such games on ZRF, but are they fair? They just hide some of the information from the person . AI perfectly sees all the figures! You must agree that such a “one gate” game has little in common with the fact that all players have incomplete information. Apparently, this is one of the reasons why so few card games are implemented for ZoG. Not very interesting to play with someone who knows all your cards. There is another side to this question. I have already mentioned Battle vs Chess more than once. Most of the missions in the campaigns of this game are based on the fact that people and computers play according to different rules. For example, in the “Point of no return” mission it is required to lure the enemy's pieces to the mines located on the field. But if the AI ​​knows the location of the mines, it simply will not go to these fields! What is the point of making a move, as a result of which you simply lose a piece? In order for the game to proceed as it was intended by the developers, the computer must “think” that it plays by the usual rules. This is also a variant of the game with incomplete information. We talked a lot about AI, now you can talk a little bit about what might not seem very important - about the design. As an illustration, I propose to consider the game Surakarta . Yes, it is implemented on ZRF, but try to watch how it plays . All clear? I do not really. The capture, in this game, is carried out according to completely unique rules. The figure must "ride" on one or more side loops and hit the opponent's figure from behind. But ZoG does not know how to animate such a complex movement! As a result, the party turns into a rebus. It would be nice, at the level of the game, to be able to connect your visualizer. But, even in a ZRF file, the rules of visualization are mixed with the rules of AI. It is clear that it was easier for developers, but now, 3D-visualization, so simple, is no longer connected (if only because it requires completely different resources).
 We talked a lot about AI, now you can talk a little bit about what might not seem very important - about the design. As an illustration, I propose to consider the game Surakarta . Yes, it is implemented on ZRF, but try to watch how it plays . All clear? I do not really. The capture, in this game, is carried out according to completely unique rules. The figure must "ride" on one or more side loops and hit the opponent's figure from behind. But ZoG does not know how to animate such a complex movement! As a result, the party turns into a rebus. It would be nice, at the level of the game, to be able to connect your visualizer. But, even in a ZRF file, the rules of visualization are mixed with the rules of AI. It is clear that it was easier for developers, but now, 3D-visualization, so simple, is no longer connected (if only because it requires completely different resources).Source: https://habr.com/ru/post/221779/
All Articles