Updating with new uncrustify.cfg

This commit is contained in:
franck 2018-01-29 16:43:06 +01:00
parent d35f547152
commit 3b67587df6
23 changed files with 355257 additions and 354108 deletions

113
Assets/uncrustify.cfg Normal file
View File

@ -0,0 +1,113 @@
#
# My favorite format
#
newlines = LF # AUTO (default), CRLF, CR, or LF
indent_with_tabs = 0 # 1=indent to level only, 2=indent with tabs
input_tab_size = 8 # original tab size
output_tab_size = 3 # new tab size
indent_columns = output_tab_size
# indent_label = 0 # pos: absolute col, neg: relative column
indent_align_string = False # align broken strings
indent_brace = 0
indent_class = true
nl_start_of_file = remove
# nl_start_of_file_min = 0
nl_end_of_file = force
nl_end_of_file_min = 1
nl_max = 4
nl_before_block_comment = 2
nl_after_func_body = 2
nl_after_func_proto_group = 2
nl_assign_brace = add # "= {" vs "= \n {"
nl_enum_brace = add # "enum {" vs "enum \n {"
nl_union_brace = add # "union {" vs "union \n {"
nl_struct_brace = add # "struct {" vs "struct \n {"
nl_do_brace = add # "do {" vs "do \n {"
nl_if_brace = add # "if () {" vs "if () \n {"
nl_for_brace = add # "for () {" vs "for () \n {"
nl_else_brace = add # "else {" vs "else \n {"
nl_while_brace = add # "while () {" vs "while () \n {"
nl_switch_brace = add # "switch () {" vs "switch () \n {"
nl_func_var_def_blk = 1
nl_before_case = 1
nl_fcall_brace = add # "foo() {" vs "foo()\n{"
nl_fdef_brace = add # "int foo() {" vs "int foo()\n{"
nl_after_return = TRUE
nl_brace_while = remove
nl_brace_else = add
nl_squeeze_ifdef = TRUE
pos_bool = trail # BOOL ops on trailing end
eat_blanks_before_close_brace = TRUE
eat_blanks_after_open_brace = TRUE
mod_paren_on_return = add # "return 1;" vs "return (1);"
mod_full_brace_if = add # "if (a) a--;" vs "if (a) { a--; }"
mod_full_brace_for = add # "for () a--;" vs "for () { a--; }"
mod_full_brace_do = add # "do a--; while ();" vs "do { a--; } while ();"
mod_full_brace_while = add # "while (a) a--;" vs "while (a) { a--; }"
sp_before_byref = remove
sp_before_semi = remove
sp_paren_paren = remove # space between (( and ))
sp_return_paren = remove # "return (1);" vs "return(1);"
sp_sizeof_paren = remove # "sizeof (int)" vs "sizeof(int)"
sp_before_sparen = force # "if (" vs "if("
sp_after_sparen = force # "if () {" vs "if (){"
sp_after_cast = remove # "(int) a" vs "(int)a"
sp_inside_braces = force # "{ 1 }" vs "{1}"
sp_inside_braces_struct = force # "{ 1 }" vs "{1}"
sp_inside_braces_enum = force # "{ 1 }" vs "{1}"
sp_inside_paren = remove
sp_inside_fparen = remove
sp_inside_sparen = remove
sp_inside_square = remove
#sp_type_func = ignore
sp_assign = force
sp_arith = force
sp_bool = force
sp_compare = force
sp_assign = force
sp_after_comma = force
sp_func_def_paren = remove # "int foo (){" vs "int foo(){"
sp_func_call_paren = remove # "foo (" vs "foo("
sp_func_proto_paren = remove # "int foo ();" vs "int foo();"
sp_func_class_paren = remove
sp_before_angle = force
sp_after_angle = force
sp_inside_angle = remove
sp_sparen_brace = add
sp_fparen_brace = add
sp_after_ptr_star = remove
sp_before_ptr_star = force
sp_between_ptr_star = remove
align_with_tabs = FALSE # use tabs to align
align_on_tabstop = FALSE # align on tabstops
align_enum_equ_span = 4
align_nl_cont = TRUE
align_var_def_span = 1
align_var_def_thresh = 12
align_var_def_inline = TRUE
#align_var_def_star = TRUE
align_var_def_colon = TRUE
align_assign_span = 1
align_assign_thresh = 12
align_struct_init_span = 3
align_var_struct_span = 99
align_right_cmt_span = 3
align_pp_define_span = 3
align_pp_define_gap = 4
align_number_right = TRUE
align_typedef_span = 5
align_typedef_gap = 3
cmt_star_cont = TRUE

View File

@ -4,362 +4,479 @@
#include "GridFunctions.hpp"
#include <algorithm>
#define IFTRACES ((debugTracesPlayer(_playerIndex)) && (traceMask & DEBUG_MASK_GRIDS))
#define IFTRACES ((debugTracesPlayer(_playerIndex)) && (traceMask & DEBUG_MASK_GRIDS))
Bot::Bot(int playerIndex) {
_playerIndex=playerIndex;
initBot();
Bot::Bot(int playerIndex)
{
_playerIndex = playerIndex;
initBot();
}
void Bot::initBot() {
calculatedBestCellToDropABomb=0;
calculatedBestCellToPickUpBonus=0;
for (int j=0; j<grid_size_y; j++) {
for (int i=0; i<grid_size_x; i++) {
bestExplosionsGrid[i][j]=0;
noDangerGrid[i][j]=false;
}
}
_direction1FrameAgo=button_error;
_direction2FramesAgo=button_error;
_shiveringCounter=0;
void Bot::initBot()
{
calculatedBestCellToDropABomb = 0;
calculatedBestCellToPickUpBonus = 0;
for (int j = 0; j < grid_size_y; j++)
{
for (int i = 0; i < grid_size_x; i++)
{
bestExplosionsGrid[i][j] = 0;
noDangerGrid[i][j] = false;
}
}
_direction1FrameAgo = button_error;
_direction2FramesAgo = button_error;
_shiveringCounter = 0;
}
bool Bot::cellSafe(int cell) {
int cellX=CELLX(cell);
int cellY=CELLY(cell);
return (!dangerGrid[cellX][cellY] && !flameGrid[cellX][cellY]);
bool Bot::cellSafe(int cell)
{
int cellX = CELLX(cell);
int cellY = CELLY(cell);
return(!dangerGrid[cellX][cellY] && !flameGrid[cellX][cellY]);
}
int Bot::bestBonusCell() {
if (!isAboutToWin() && travelGrid.cost(calculatedBestCellToPickUpBonus)!=TRAVELCOST_CANTGO
&& cellSafe(calculatedBestCellToPickUpBonus))
{
return calculatedBestCellToPickUpBonus;
} else {
return -1;
}
int Bot::bestBonusCell()
{
if (!isAboutToWin() && travelGrid.cost(calculatedBestCellToPickUpBonus) != TRAVELCOST_CANTGO &&
cellSafe(calculatedBestCellToPickUpBonus))
{
return(calculatedBestCellToPickUpBonus);
}
else
{
return(-1);
}
}
int Bot::scoreForBonus(Bonus bonus,int x,int y) {
if (!bonusPlayerWouldLike(_playerIndex,bonus)) {
if (((bonus==bonus_remote) || (bonus==bonus_egg) || (bonus==bonus_roller)) && (isPlayerFastestToCell(_playerIndex,x,y))) {
if (isSameTeamTwoFastestToCell(x,y)) {
if (tracesDecisions(_playerIndex)) log_debug("%d we are the fastest 2 to bonus %d (%d/%d) ignoring\n",_playerIndex,bonus,x,y);
return 0;
} else {
if (tracesDecisions(_playerIndex)) log_debug("%d should pick bonus %d (%d/%d) for safety reason\n",_playerIndex,bonus,x,y);
}
}
}
int distance=travelSafeGrid.cost(x,y);
if (distance==TRAVELCOST_CANTGO) return 0;
switch (bonus)
{
case bonus_push:
case bonus_remote:
case bonus_bulletproofjacket:
distance/=4;
break;
case bonus_egg:
case bonus_heart:
case bonus_roller:
distance/=8;
break;
default:
break;
}
if (distance<100) {
return (TRAVELCOST_CANTGO-distance);
} else {
if (isPlayerFastestToCell(_playerIndex,x,y)) {
return (TRAVELCOST_CANTGO-distance);
}
}
return 0;
int Bot::scoreForBonus(Bonus bonus, int x, int y)
{
if (!bonusPlayerWouldLike(_playerIndex, bonus))
{
if (((bonus == bonus_remote) || (bonus == bonus_egg) || (bonus == bonus_roller)) && (isPlayerFastestToCell(_playerIndex, x, y)))
{
if (isSameTeamTwoFastestToCell(x, y))
{
if (tracesDecisions(_playerIndex))
{
log_debug("%d we are the fastest 2 to bonus %d (%d/%d) ignoring\n", _playerIndex, bonus, x, y);
}
return(0);
}
else
{
if (tracesDecisions(_playerIndex))
{
log_debug("%d should pick bonus %d (%d/%d) for safety reason\n", _playerIndex, bonus, x, y);
}
}
}
}
int distance = travelSafeGrid.cost(x, y);
if (distance == TRAVELCOST_CANTGO)
{
return(0);
}
switch (bonus)
{
case bonus_push:
case bonus_remote:
case bonus_bulletproofjacket:
distance /= 4;
break;
case bonus_egg:
case bonus_heart:
case bonus_roller:
distance /= 8;
break;
default:
break;
}
if (distance < 100)
{
return(TRAVELCOST_CANTGO - distance);
}
else
{
if (isPlayerFastestToCell(_playerIndex, x, y))
{
return(TRAVELCOST_CANTGO - distance);
}
}
return(0);
}
uint8_t Bot::calculateBestCellToPickUpBonus() {
int bestCell=-1;
int bestScore=0;
for (int j=0; j<grid_size_y; j++) {
for (int i=0; i<grid_size_x; i++) {
Bonus bonus=bonusInCell(i,j);
if (bonus!=no_bonus) {
int score=scoreForBonus(bonus,i,j);
if (score>bestScore) {
int cellIndex=CELLINDEX(i,j);
bestCell=cellIndex;
bestScore=score;
}
}
}
}
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/calculateBestCellToPickUpBonus: %d/%d:bestCell=%d bestScore=%d\n",frameNumber(),_playerIndex,bestCell,bestScore);
return bestCell;
uint8_t Bot::calculateBestCellToPickUpBonus()
{
int bestCell = -1;
int bestScore = 0;
for (int j = 0; j < grid_size_y; j++)
{
for (int i = 0; i < grid_size_x; i++)
{
Bonus bonus = bonusInCell(i, j);
if (bonus != no_bonus)
{
int score = scoreForBonus(bonus, i, j);
if (score > bestScore)
{
int cellIndex = CELLINDEX(i, j);
bestCell = cellIndex;
bestScore = score;
}
}
}
}
if (tracesDecisions(_playerIndex))
{
log_debug("BOTTREEDECISIONS/calculateBestCellToPickUpBonus: %d/%d:bestCell=%d bestScore=%d\n", frameNumber(), _playerIndex, bestCell, bestScore);
}
return(bestCell);
}
int noise(int player,int x,int y) {
return (x+player+y)%nb_dyna;
int noise(int player, int x, int y)
{
return((x + player + y) % nb_dyna);
}
int Bot::bestCellToDropABomb()
{
int bestCell = -1;
int bestScore = 0;
int Bot::bestCellToDropABomb() {
int bestCell=-1;
int bestScore=0;
for (int j=0; j<grid_size_y; j++) {
for (int i=0; i<grid_size_x; i++) {
for (int j = 0; j < grid_size_y; j++)
{
for (int i = 0; i < grid_size_x; i++)
{
int score = bestExplosionsGrid[i][j] * 128;
if (score)
{
score += noise(_playerIndex, i, j);
}
int travelCost = 1 + travelGrid.cost(i, j) / 16;
if (score > travelCost)
{
score = score / travelCost;
}
int score=bestExplosionsGrid[i][j]*128;
if (score) score+=noise(_playerIndex,i,j);
int travelCost=1+travelGrid.cost(i,j)/16;
if (score>travelCost) {
score=score/travelCost;
}
if (score>bestScore) {
bestCell=CELLINDEX(i,j);
bestScore=score;
}
}
}
return bestCell;
if (score > bestScore)
{
bestCell = CELLINDEX(i, j);
bestScore = score;
}
}
}
return(bestCell);
}
int Bot::bestSafeCell() {
int bestCell=cellPlayer(_playerIndex);
int bestScore=0;
for (int j=0; j<grid_size_y; j++) {
for (int i=0; i<grid_size_x; i++) {
if (!somethingThatIsNoTABombAndThatWouldStopPlayer(i,j)) {
int score=TRAVELCOST_CANTGO-travelGrid.cost(i,j);
if ((score>bestScore) && cellSafe(CELLINDEX(i,j))) {
int cellIndex=CELLINDEX(i,j);
bestCell=cellIndex;
bestScore=score;
}
}
}
}
return bestCell;
int Bot::bestSafeCell()
{
int bestCell = cellPlayer(_playerIndex);
int bestScore = 0;
for (int j = 0; j < grid_size_y; j++)
{
for (int i = 0; i < grid_size_x; i++)
{
if (!somethingThatIsNoTABombAndThatWouldStopPlayer(i, j))
{
int score = TRAVELCOST_CANTGO - travelGrid.cost(i, j);
if ((score > bestScore) && cellSafe(CELLINDEX(i, j)))
{
int cellIndex = CELLINDEX(i, j);
bestCell = cellIndex;
bestScore = score;
}
}
}
}
return(bestCell);
}
#define MAX_PIXELS_PER_FRAME 8
#define MAX_PIXELS_PER_FRAME 8
bool Bot::isSomewhatInTheMiddleOfCell() {
int x=GETXPIXELSTOCENTEROFCELL(_playerIndex);
int y=GETYPIXELSTOCENTEROFCELL(_playerIndex);
return ((x>-MAX_PIXELS_PER_FRAME/2) && (x<MAX_PIXELS_PER_FRAME/2) && (y<MAX_PIXELS_PER_FRAME/2) && (y>-MAX_PIXELS_PER_FRAME/2));
bool Bot::isSomewhatInTheMiddleOfCell()
{
int x = GETXPIXELSTOCENTEROFCELL(_playerIndex);
int y = GETYPIXELSTOCENTEROFCELL(_playerIndex);
return((x > -MAX_PIXELS_PER_FRAME / 2) && (x < MAX_PIXELS_PER_FRAME / 2) && (y < MAX_PIXELS_PER_FRAME / 2) && (y > -MAX_PIXELS_PER_FRAME / 2));
}
bool Bot::amISafe() {
return cellSafe(cellPlayer(_playerIndex));
bool Bot::amISafe()
{
return(cellSafe(cellPlayer(_playerIndex)));
}
bool Bot::isThereABombUnderMe() {
int x=xPlayer(_playerIndex);
int y=yPlayer(_playerIndex);
return bombInCell(x,y);
bool Bot::isThereABombUnderMe()
{
int x = xPlayer(_playerIndex);
int y = yPlayer(_playerIndex);
return(bombInCell(x, y));
}
int Bot::howManyBombsLeft() {
return nbBombsLeft(_playerIndex);
int Bot::howManyBombsLeft()
{
return(nbBombsLeft(_playerIndex));
}
void Bot::printGrid()
{
if (IFTRACES) {
for (int j=0; j<grid_size_y; j++) {
for (int i=0; i<grid_size_x; i++) {
db brickKind=m.truc[i+j*grid_size_x_with_padding];
if (monsterInCell(i,j) || playerInCell(i,j)) {
if (monsterInCell(i,j)) {
log_debug(" 8( ");
} else {
log_debug(" 8) ");
}
} else {
switch (brickKind) {
case 1:
log_debug("[======]");
break;
case 2:
log_debug("(******)");
break;
default:
if (no_bonus!=bonusInCell(i,j)) {
log_debug(" (%d) ",bonusInCell(i,j));
} else {
log_debug(" ");
}
break;
}
}
}
log_debug("\n");
}
log_debug("bestExplosionsGrid player %d\n",_playerIndex);
for (int j=0; j<grid_size_y; j++) {
for (int i=0; i<grid_size_x; i++) {
log_debug("%04d",bestExplosionsGrid[i][j]);
if (dangerGrid[i][j]) {
log_debug("x");
} else {
log_debug("_");
}
}
log_debug("\n");
}
log_debug("travelCostGrid %d/%d cell:%d x:%d y:%d adderX=%d adderY=%d\n",frameNumber(),_playerIndex,cellPlayer(_playerIndex), xPlayer(_playerIndex),yPlayer(_playerIndex),GETXPIXELSTOCENTEROFCELL(_playerIndex)*framesToCrossACell(_playerIndex)/CELLPIXELSSIZE,
GETYPIXELSTOCENTEROFCELL(_playerIndex)*framesToCrossACell(_playerIndex)/CELLPIXELSSIZE);
travelGrid.print();
if (IFTRACES)
{
for (int j = 0; j < grid_size_y; j++)
{
for (int i = 0; i < grid_size_x; i++)
{
db brickKind = m.truc[i + j * grid_size_x_with_padding];
if (monsterInCell(i, j) || playerInCell(i, j))
{
if (monsterInCell(i, j))
{
log_debug(" 8( ");
}
else
{
log_debug(" 8) ");
}
}
else
{
switch (brickKind)
{
case 1:
log_debug("[======]");
break;
log_debug("travelCostSafeGrid\n");
travelSafeGrid.print();
case 2:
log_debug("(******)");
break;
log_debug("%d flameGrid player %d\n",m.changement,_playerIndex);
for (int j=0; j<grid_size_y; j++) {
for (int i=0; i<grid_size_x; i++) {
log_debug("%04d ",flameGrid[i][j]);
}
log_debug("\n");
}
log_debug("hasRemote=%d isCellCulDeSac=%d flamesize:%d lapipipino:%d lapipipino5:%d amISafe=%d\n",hasRemote(_playerIndex),isCellCulDeSac(xPlayer(_playerIndex),yPlayer(_playerIndex)),flameSize(_playerIndex),m.lapipipino[_playerIndex],m.lapipipino5[_playerIndex],amISafe());
}
default:
if (no_bonus != bonusInCell(i, j))
{
log_debug(" (%d) ", bonusInCell(i, j));
}
else
{
log_debug(" ");
}
break;
}
}
}
log_debug("\n");
}
log_debug("bestExplosionsGrid player %d\n", _playerIndex);
for (int j = 0; j < grid_size_y; j++)
{
for (int i = 0; i < grid_size_x; i++)
{
log_debug("%04d", bestExplosionsGrid[i][j]);
if (dangerGrid[i][j])
{
log_debug("x");
}
else
{
log_debug("_");
}
}
log_debug("\n");
}
log_debug("travelCostGrid %d/%d cell:%d x:%d y:%d adderX=%d adderY=%d\n", frameNumber(), _playerIndex, cellPlayer(_playerIndex), xPlayer(_playerIndex), yPlayer(_playerIndex), GETXPIXELSTOCENTEROFCELL(_playerIndex) * framesToCrossACell(_playerIndex) / CELLPIXELSSIZE,
GETYPIXELSTOCENTEROFCELL(_playerIndex) * framesToCrossACell(_playerIndex) / CELLPIXELSSIZE);
travelGrid.print();
log_debug("travelCostSafeGrid\n");
travelSafeGrid.print();
log_debug("%d flameGrid player %d\n", m.changement, _playerIndex);
for (int j = 0; j < grid_size_y; j++)
{
for (int i = 0; i < grid_size_x; i++)
{
log_debug("%04d ", flameGrid[i][j]);
}
log_debug("\n");
}
log_debug("hasRemote=%d isCellCulDeSac=%d flamesize:%d lapipipino:%d lapipipino5:%d amISafe=%d\n", hasRemote(_playerIndex), isCellCulDeSac(xPlayer(_playerIndex), yPlayer(_playerIndex)), flameSize(_playerIndex), m.lapipipino[_playerIndex], m.lapipipino5[_playerIndex], amISafe());
}
}
void Bot::stopWalking() {
mrboom_update_input(button_up,_playerIndex,0,true);
mrboom_update_input(button_down,_playerIndex,0,true);
mrboom_update_input(button_left,_playerIndex,0,true);
mrboom_update_input(button_right,_playerIndex,0,true);
void Bot::stopWalking()
{
mrboom_update_input(button_up, _playerIndex, 0, true);
mrboom_update_input(button_down, _playerIndex, 0, true);
mrboom_update_input(button_left, _playerIndex, 0, true);
mrboom_update_input(button_right, _playerIndex, 0, true);
}
void Bot::startPushingRemoteButton() {
mrboom_update_input(button_a,_playerIndex,1,true);
void Bot::startPushingRemoteButton()
{
mrboom_update_input(button_a, _playerIndex, 1, true);
}
void Bot::stopPushingRemoteButton() {
mrboom_update_input(button_a,_playerIndex,0,true);
void Bot::stopPushingRemoteButton()
{
mrboom_update_input(button_a, _playerIndex, 0, true);
}
void Bot::startPushingJumpButton() {
mrboom_update_input(button_x,_playerIndex,1,true);
void Bot::startPushingJumpButton()
{
mrboom_update_input(button_x, _playerIndex, 1, true);
}
void Bot::stopPushingJumpButton() {
mrboom_update_input(button_x,_playerIndex,0,true);
void Bot::stopPushingJumpButton()
{
mrboom_update_input(button_x, _playerIndex, 0, true);
}
void Bot::startPushingBombDropButton() {
pushingDropBombButton=true;
mrboom_update_input(button_b,_playerIndex,1,true);
void Bot::startPushingBombDropButton()
{
pushingDropBombButton = true;
mrboom_update_input(button_b, _playerIndex, 1, true);
}
void Bot::stopPushingBombDropButton() {
pushingDropBombButton=false;
mrboom_update_input(button_b,_playerIndex,0,true);
void Bot::stopPushingBombDropButton()
{
pushingDropBombButton = false;
mrboom_update_input(button_b, _playerIndex, 0, true);
}
#ifdef DEBUG
extern int howToGoDebug;
#endif
bool Bot::walkToCell(int cell) {
#ifdef DEBUG
howToGoDebug=0;
#endif
bool shouldJump=false;
enum Button direction = howToGo(_playerIndex,CELLX(cell), CELLY(cell), travelSafeGrid, shouldJump);
if (direction==button_error) {
direction = howToGo(_playerIndex,CELLX(cell), CELLY(cell), travelGrid, shouldJump);
}
bool Bot::walkToCell(int cell)
{
#ifdef DEBUG
howToGoDebug = 0;
#endif
bool shouldJump = false;
enum Button direction = howToGo(_playerIndex, CELLX(cell), CELLY(cell), travelSafeGrid, shouldJump);
if (direction == button_error)
{
direction = howToGo(_playerIndex, CELLX(cell), CELLY(cell), travelGrid, shouldJump);
}
#ifdef DEBUG
walkingToCell[_playerIndex]=cell;
if (tracesDecisions(_playerIndex)) {
char * directionText=(char *)"?";
switch (direction) {
case button_up:
directionText=(char *)"button_up";
break;
case button_down:
directionText=(char *)"button_down";
break;
case button_left:
directionText=(char *)"button_left";
break;
case button_right:
directionText=(char *)"button_right";
break;
default:
break;
}
log_debug("\nBOTTREEDECISIONS: %d/%d:howToGo to %d:%s %d/%d shouldjump=%d\n",frameNumber(),_playerIndex,cell,directionText,GETXPIXELSTOCENTEROFCELL(_playerIndex),GETYPIXELSTOCENTEROFCELL(_playerIndex),shouldJump);
}
#endif
stopWalking();
#ifdef DEBUG
walkingToCell[_playerIndex] = cell;
if (tracesDecisions(_playerIndex))
{
char *directionText = (char *)"?";
switch (direction)
{
case button_up:
directionText = (char *)"button_up";
break;
if (shouldJump) {
startPushingJumpButton();
}
case button_down:
directionText = (char *)"button_down";
break;
if (hasInvertedDisease(_playerIndex)) {
switch (direction) {
case button_up:
direction=button_down;
break;
case button_down:
direction=button_up;
break;
case button_left:
direction=button_right;
break;
case button_right:
direction=button_left;
break;
default:
break;
}
}
case button_left:
directionText = (char *)"button_left";
break;
mrboom_update_input(direction,_playerIndex,1,true);
case button_right:
directionText = (char *)"button_right";
break;
#define MAX_SHIVERING 3
if ((_direction2FramesAgo==direction) && (_direction1FrameAgo!=direction)) {
_shiveringCounter++;
if (_shiveringCounter>=MAX_SHIVERING) {
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingBombDropButton\n",frameNumber(),_playerIndex);
startPushingBombDropButton();
}
if (_shiveringCounter>=MAX_SHIVERING*2) {
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingJumpButton\n",frameNumber(),_playerIndex);
startPushingJumpButton();
}
if (_shiveringCounter>=MAX_SHIVERING*3) {
if (tracesDecisions(_playerIndex)) log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingRemoteButton\n",frameNumber(),_playerIndex);
startPushingRemoteButton();
}
} else {
_shiveringCounter=0;
}
_direction2FramesAgo=_direction1FrameAgo;
_direction1FrameAgo=direction;
default:
break;
}
log_debug("\nBOTTREEDECISIONS: %d/%d:howToGo to %d:%s %d/%d shouldjump=%d\n", frameNumber(), _playerIndex, cell, directionText, GETXPIXELSTOCENTEROFCELL(_playerIndex), GETYPIXELSTOCENTEROFCELL(_playerIndex), shouldJump);
}
#endif
stopWalking();
return (direction!=button_error);
if (shouldJump)
{
startPushingJumpButton();
}
if (hasInvertedDisease(_playerIndex))
{
switch (direction)
{
case button_up:
direction = button_down;
break;
case button_down:
direction = button_up;
break;
case button_left:
direction = button_right;
break;
case button_right:
direction = button_left;
break;
default:
break;
}
}
mrboom_update_input(direction, _playerIndex, 1, true);
#define MAX_SHIVERING 3
if ((_direction2FramesAgo == direction) && (_direction1FrameAgo != direction))
{
_shiveringCounter++;
if (_shiveringCounter >= MAX_SHIVERING)
{
if (tracesDecisions(_playerIndex))
{
log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingBombDropButton\n", frameNumber(), _playerIndex);
}
startPushingBombDropButton();
}
if (_shiveringCounter >= MAX_SHIVERING * 2)
{
if (tracesDecisions(_playerIndex))
{
log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingJumpButton\n", frameNumber(), _playerIndex);
}
startPushingJumpButton();
}
if (_shiveringCounter >= MAX_SHIVERING * 3)
{
if (tracesDecisions(_playerIndex))
{
log_debug("BOTTREEDECISIONS/shivering on bot: %d/%d ->startPushingRemoteButton\n", frameNumber(), _playerIndex);
}
startPushingRemoteButton();
}
}
else
{
_shiveringCounter = 0;
}
_direction2FramesAgo = _direction1FrameAgo;
_direction1FrameAgo = direction;
return(direction != button_error);
}
int Bot::getCurrentCell() {
int x=xPlayer(_playerIndex);
int y=yPlayer(_playerIndex);
return CELLINDEX(x,y);
int Bot::getCurrentCell()
{
int x = xPlayer(_playerIndex);
int y = yPlayer(_playerIndex);
return(CELLINDEX(x, y));
}
void Bot::printCellInfo(int cell) {
log_debug("printCellInfoBot Cell:%d Bot:%d: travelCostGrid=%d bestExplosionsGrid=%d flameGrid=%d dangerGrid=%d\n", cell,_playerIndex,travelGrid.cost(cell),bestExplosionsGrid[CELLX(cell)][CELLY(cell)],flameGrid[CELLX(cell)][CELLY(cell)],dangerGrid[CELLX(cell)][CELLY(cell)]);
void Bot::printCellInfo(int cell)
{
log_debug("printCellInfoBot Cell:%d Bot:%d: travelCostGrid=%d bestExplosionsGrid=%d flameGrid=%d dangerGrid=%d\n", cell, _playerIndex, travelGrid.cost(cell), bestExplosionsGrid[CELLX(cell)][CELLY(cell)], flameGrid[CELLX(cell)][CELLY(cell)], dangerGrid[CELLX(cell)][CELLY(cell)]);
}

View File

@ -5,42 +5,43 @@
class Bot {
public:
Bot(int playerIndex);
void initBot();
int bestBonusCell();
int bestCellToDropABomb();
int bestSafeCell();
bool isSomewhatInTheMiddleOfCell();
bool isThereABombUnderMe();
void stopWalking();
void startPushingBombDropButton();
void startPushingRemoteButton();
void startPushingJumpButton();
void stopPushingBombDropButton();
void stopPushingRemoteButton();
void stopPushingJumpButton();
bool walkToCell(int cell);
bool amISafe();
int getCurrentCell();
void printGrid();
void printCellInfo(int cell);
int howManyBombsLeft();
uint8_t calculateBestCellToPickUpBonus();
bool cellSafe(int cell);
int scoreForBonus(Bonus bonus,int x,int y);
int _playerIndex;
uint8_t _direction1FrameAgo;
uint8_t _direction2FramesAgo;
uint8_t _shiveringCounter;
Bot(int playerIndex);
void initBot();
int bestBonusCell();
int bestCellToDropABomb();
int bestSafeCell();
bool isSomewhatInTheMiddleOfCell();
bool isThereABombUnderMe();
void stopWalking();
void startPushingBombDropButton();
void startPushingRemoteButton();
void startPushingJumpButton();
void stopPushingBombDropButton();
void stopPushingRemoteButton();
void stopPushingJumpButton();
bool walkToCell(int cell);
bool amISafe();
int getCurrentCell();
void printGrid();
void printCellInfo(int cell);
int howManyBombsLeft();
uint8_t calculateBestCellToPickUpBonus();
bool cellSafe(int cell);
int scoreForBonus(Bonus bonus, int x, int y);
int _playerIndex;
uint8_t _direction1FrameAgo;
uint8_t _direction2FramesAgo;
uint8_t _shiveringCounter;
public:
travelCostGrid travelGrid; // travelGrid that can cross cells set to true in DangerGrid
travelCostGrid travelSafeGrid; // travelGrid avoiding cells set to true in DangerGrid
uint32_t bestExplosionsGrid[grid_size_x][grid_size_y]; // score based on the nb of bricks one of my bomb there would break or of the proximity from a monster
uint8_t calculatedBestCellToPickUpBonus;
uint8_t calculatedBestCellToDropABomb;
uint32_t flameGrid[grid_size_x][grid_size_y]; // 0: no flame, 1..FLAME_DURATION+1: time with a flame, FLAME_DURATION+2: time before end of flame
bool dangerGrid[grid_size_x][grid_size_y]; // used to track all dangers, including the ones we don't know the timing: true means a flame is coming (possibily under a remote controled bomb...), or that a monster is there
bool noDangerGrid[grid_size_x][grid_size_y]; // set to false for each cells at init, used as an empty dangerGrid instance.
bool monsterIsComingGrid[NUMBER_OF_CELLS];
bool pushingDropBombButton;
travelCostGrid travelGrid; // travelGrid that can cross cells set to true in DangerGrid
travelCostGrid travelSafeGrid; // travelGrid avoiding cells set to true in DangerGrid
uint32_t bestExplosionsGrid[grid_size_x][grid_size_y]; // score based on the nb of bricks one of my bomb there would break or of the proximity from a monster
uint8_t calculatedBestCellToPickUpBonus;
uint8_t calculatedBestCellToDropABomb;
uint32_t flameGrid[grid_size_x][grid_size_y]; // 0: no flame, 1..FLAME_DURATION+1: time with a flame, FLAME_DURATION+2: time before end of flame
bool dangerGrid[grid_size_x][grid_size_y]; // used to track all dangers, including the ones we don't know the timing: true means a flame is coming (possibily under a remote controled bomb...), or that a monster is there
bool noDangerGrid[grid_size_x][grid_size_y]; // set to false for each cells at init, used as an empty dangerGrid instance.
bool monsterIsComingGrid[NUMBER_OF_CELLS];
bool pushingDropBombButton;
};

View File

@ -3,235 +3,302 @@
#include "BotTree.hpp"
#ifdef IOS
void std::__throw_out_of_range(char const*) {
void std::__throw_out_of_range(char const *)
{
}
#endif
class ConditionNode : public bt::Node
{
public:
ConditionNode(Bot * bot) : Node(), bot(bot) {
}
void Initialize() {
}
virtual bool Condition() = 0;
bt::Status Update()
{
if (Condition())
return bt::Success;
return bt::Failure;
}
ConditionNode(Bot *bot) : Node(), bot(bot)
{
}
void Initialize()
{
}
virtual bool Condition() = 0;
bt::Status Update()
{
if (Condition())
{
return(bt::Success);
}
return(bt::Failure);
}
protected:
Bot * bot;
Bot *bot;
};
class MoveToNode : public bt::Node
{
public:
MoveToNode(Bot * bot) : Node(), bot(bot) {
}
void Initialize() {
}
virtual int Cell() = 0;
bt::Status Update()
{
int cell=Cell();
if (cell==-1) {
if (isInMiddleOfCell(bot->_playerIndex)) {
bot->stopWalking();
}
return bt::Failure;
}
MoveToNode(Bot *bot) : Node(), bot(bot)
{
}
if (((!(isInMiddleOfCell(bot->_playerIndex) && bot->getCurrentCell()==cell))) || (bot->getCurrentCell()!=cell))
{
if (bot->walkToCell(cell))
return bt::Running;
void Initialize()
{
}
virtual int Cell() = 0;
bt::Status Update()
{
int cell = Cell();
if (cell == -1)
{
if (isInMiddleOfCell(bot->_playerIndex))
{
bot->stopWalking();
}
return(bt::Failure);
}
if (((!(isInMiddleOfCell(bot->_playerIndex) && bot->getCurrentCell() == cell))) || (bot->getCurrentCell() != cell))
{
if (bot->walkToCell(cell))
{
return(bt::Running);
}
if (tracesDecisions(bot->_playerIndex))
{
log_debug("BOTTREEDECISIONS: %d/%d:Failed to go to %d (%d/%d)\n", frameNumber(), bot->_playerIndex, cell, CELLX(cell), CELLY(cell));
}
return(bt::Failure);
}
bot->stopWalking();
if (tracesDecisions(bot->_playerIndex))
{
log_debug("BOTTREEDECISIONS: %d/%d:stopWalking arrived in %d (%d/%d)\n", frameNumber(), bot->_playerIndex, cell, CELLX(cell), CELLY(cell));
}
return(bt::Success);
}
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:Failed to go to %d (%d/%d)\n",frameNumber(),bot->_playerIndex,cell,CELLX(cell),CELLY(cell));
return bt::Failure;
}
bot->stopWalking();
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:stopWalking arrived in %d (%d/%d)\n",frameNumber(),bot->_playerIndex,cell,CELLX(cell),CELLY(cell));
return bt::Success;
}
protected:
Bot * bot;
Bot *bot;
};
class MoveToBonus : public MoveToNode
{
public:
MoveToBonus(Bot * bot) : MoveToNode(bot) {
}
int Cell() {
int bestCell=bot->bestBonusCell();
MoveToBonus(Bot *bot) : MoveToNode(bot)
{
}
int Cell()
{
int bestCell = bot->bestBonusCell();
#ifdef DEBUG
botStates[bot->_playerIndex]=goingBonus;
botStates[bot->_playerIndex] = goingBonus;
#endif
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:gotoBonus:%d (%d/%d) current=%d (%d/%d)\n",frameNumber(),bot->_playerIndex,bestCell,CELLX(bestCell),CELLY(bestCell),bot->getCurrentCell(),CELLX(bot->getCurrentCell()),CELLY(bot->getCurrentCell()));
return bestCell;
}
if (tracesDecisions(bot->_playerIndex))
{
log_debug("BOTTREEDECISIONS: %d/%d:gotoBonus:%d (%d/%d) current=%d (%d/%d)\n", frameNumber(), bot->_playerIndex, bestCell, CELLX(bestCell), CELLY(bestCell), bot->getCurrentCell(), CELLX(bot->getCurrentCell()), CELLY(bot->getCurrentCell()));
}
return(bestCell);
}
};
class MoveToBombBestBombCell : public MoveToNode
{
public:
MoveToBombBestBombCell(Bot * bot) : MoveToNode(bot) {
}
int Cell() {
int bestCell=bot->bestCellToDropABomb();
MoveToBombBestBombCell(Bot *bot) : MoveToNode(bot)
{
}
int Cell()
{
int bestCell = bot->bestCellToDropABomb();
#ifdef DEBUG
botStates[bot->_playerIndex]=goingBomb;
botStates[bot->_playerIndex] = goingBomb;
#endif
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:gotoBestBombCell:%d (%d/%d) current=%d (%d/%d)\n",frameNumber(),bot->_playerIndex,bestCell,CELLX(bestCell),CELLY(bestCell),bot->getCurrentCell(),CELLX(bot->getCurrentCell()),CELLY(bot->getCurrentCell()));
return bestCell;
}
if (tracesDecisions(bot->_playerIndex))
{
log_debug("BOTTREEDECISIONS: %d/%d:gotoBestBombCell:%d (%d/%d) current=%d (%d/%d)\n", frameNumber(), bot->_playerIndex, bestCell, CELLX(bestCell), CELLY(bestCell), bot->getCurrentCell(), CELLX(bot->getCurrentCell()), CELLY(bot->getCurrentCell()));
}
return(bestCell);
}
};
class MoveToSafeCell : public MoveToNode
{
public:
MoveToSafeCell(Bot * bot) : MoveToNode(bot) {
}
int Cell() {
int bestCell=bot->bestSafeCell();
MoveToSafeCell(Bot *bot) : MoveToNode(bot)
{
}
int Cell()
{
int bestCell = bot->bestSafeCell();
#ifdef DEBUG
botStates[bot->_playerIndex]=goingSafe;
botStates[bot->_playerIndex] = goingSafe;
#endif
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:gotoBestSafeCell:%d (%d/%d) current=%d (%d/%d)\n",frameNumber(),bot->_playerIndex,bestCell,CELLX(bestCell),CELLY(bestCell),bot->getCurrentCell(),CELLX(bot->getCurrentCell()),CELLY(bot->getCurrentCell()));
return bestCell;
}
if (tracesDecisions(bot->_playerIndex))
{
log_debug("BOTTREEDECISIONS: %d/%d:gotoBestSafeCell:%d (%d/%d) current=%d (%d/%d)\n", frameNumber(), bot->_playerIndex, bestCell, CELLX(bestCell), CELLY(bestCell), bot->getCurrentCell(), CELLX(bot->getCurrentCell()), CELLY(bot->getCurrentCell()));
}
return(bestCell);
}
};
class ConditionBombsLeft : public ConditionNode
{
public:
ConditionBombsLeft(Bot * bot) : ConditionNode(bot) {
}
bool Condition() {
// condition "i have more bombs"
int howManyBombs=bot->howManyBombsLeft();
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:bombLeft:%d\n",frameNumber(),bot->_playerIndex,howManyBombs);
return (howManyBombs);
}
ConditionBombsLeft(Bot *bot) : ConditionNode(bot)
{
}
bool Condition()
{
// condition "i have more bombs"
int howManyBombs = bot->howManyBombsLeft();
if (tracesDecisions(bot->_playerIndex))
{
log_debug("BOTTREEDECISIONS: %d/%d:bombLeft:%d\n", frameNumber(), bot->_playerIndex, howManyBombs);
}
return(howManyBombs);
}
};
class ConditionDropBomb : public ConditionNode
{
public:
ConditionDropBomb(Bot * bot) : ConditionNode(bot) {
}
bool Condition() {
bot->startPushingBombDropButton(); //TOFIX ? return false or running ?
if (tracesDecisions(bot->_playerIndex)) log_debug("BOTTREEDECISIONS: %d/%d:dropBomb\n",frameNumber(),bot->_playerIndex);
return true;
}
ConditionDropBomb(Bot *bot) : ConditionNode(bot)
{
}
bool Condition()
{
bot->startPushingBombDropButton(); //TOFIX ? return false or running ?
if (tracesDecisions(bot->_playerIndex))
{
log_debug("BOTTREEDECISIONS: %d/%d:dropBomb\n", frameNumber(), bot->_playerIndex);
}
return(true);
}
};
BotTree::BotTree(int playerIndex) : Bot(playerIndex)
{
tree = new bt::BehaviorTree();
tree = new bt::BehaviorTree();
MoveToBonus * gotoBonus = new MoveToBonus(this);
bt::Sequence * bombSeq = new bt::Sequence();
MoveToBonus * gotoBonus = new MoveToBonus(this);
bt::Sequence *bombSeq = new bt::Sequence();
ConditionBombsLeft * bombLeft = new ConditionBombsLeft(this);
bombSeq->AddChild(bombLeft);
ConditionBombsLeft *bombLeft = new ConditionBombsLeft(this);
bombSeq->AddChild(bombLeft);
MoveToBombBestBombCell * gotoBestBombCell = new MoveToBombBestBombCell(this);
bombSeq->AddChild(gotoBestBombCell);
MoveToBombBestBombCell *gotoBestBombCell = new MoveToBombBestBombCell(this);
bombSeq->AddChild(gotoBestBombCell);
ConditionDropBomb * dropBomb = new ConditionDropBomb(this);
bombSeq->AddChild(dropBomb);
ConditionDropBomb *dropBomb = new ConditionDropBomb(this);
bombSeq->AddChild(dropBomb);
MoveToSafeCell * gotoSafePlace = new MoveToSafeCell(this);
bt::Selector * rootNode = new bt::Selector();
rootNode->AddChild(gotoBonus);
rootNode->AddChild(bombSeq);
rootNode->AddChild(gotoSafePlace);
tree->SetRoot(rootNode);
MoveToSafeCell *gotoSafePlace = new MoveToSafeCell(this);
bt::Selector * rootNode = new bt::Selector();
rootNode->AddChild(gotoBonus);
rootNode->AddChild(bombSeq);
rootNode->AddChild(gotoSafePlace);
tree->SetRoot(rootNode);
}
void BotTree::updateGrids()
{
updateFlameAndDangerGridsWithBombs(_playerIndex,flameGrid,dangerGrid);
updateDangerGridWithMonstersSickPlayersAndCulDeSacs(_playerIndex,dangerGrid);
updateDangerGridWithMonster4CellsTerritories(dangerGrid);
updateMonsterIsComingGrid(monsterIsComingGrid);
updateTravelGrid(_playerIndex,false,travelGrid,flameGrid,noDangerGrid);
updateTravelGrid(_playerIndex,false,travelSafeGrid,flameGrid,dangerGrid);
updateFlameAndDangerGridsWithBombs(_playerIndex, flameGrid, dangerGrid);
updateDangerGridWithMonstersSickPlayersAndCulDeSacs(_playerIndex, dangerGrid);
updateDangerGridWithMonster4CellsTerritories(dangerGrid);
updateMonsterIsComingGrid(monsterIsComingGrid);
updateTravelGrid(_playerIndex, false, travelGrid, flameGrid, noDangerGrid);
updateTravelGrid(_playerIndex, false, travelSafeGrid, flameGrid, dangerGrid);
#ifdef DEBUG
printGrid();
printGrid();
#endif
if (!((frameNumber()+_playerIndex)%nb_dyna))
{
calculatedBestCellToPickUpBonus=calculateBestCellToPickUpBonus();
}
updateBestExplosionGrid(_playerIndex,bestExplosionsGrid,travelGrid,flameGrid,dangerGrid);
if (!((frameNumber() + _playerIndex) % nb_dyna))
{
calculatedBestCellToPickUpBonus = calculateBestCellToPickUpBonus();
}
updateBestExplosionGrid(_playerIndex, bestExplosionsGrid, travelGrid, flameGrid, dangerGrid);
}
void BotTree::tick() {
stopPushingRemoteButton();
stopPushingBombDropButton();
stopPushingJumpButton();
tree->Update();
if (monsterIsComingGrid[cellPlayer(_playerIndex)]) {
startPushingBombDropButton();
}
if (isSomewhatInTheMiddleOfCell() && frameNumber()%2 && pushingDropBombButton==false) {
bool cantPlaceMoreBombsAndSafe=(((bestCellToDropABomb()==-1) || (howManyBombsLeft()==0)) && amISafe());
if (cantPlaceMoreBombsAndSafe || shouldActivateRemote(_playerIndex)) {
startPushingRemoteButton();
}
}
void BotTree::tick()
{
stopPushingRemoteButton();
stopPushingBombDropButton();
stopPushingJumpButton();
tree->Update();
if (monsterIsComingGrid[cellPlayer(_playerIndex)])
{
startPushingBombDropButton();
}
if (isSomewhatInTheMiddleOfCell() && frameNumber() % 2 && pushingDropBombButton == false)
{
bool cantPlaceMoreBombsAndSafe = (((bestCellToDropABomb() == -1) || (howManyBombsLeft() == 0)) && amISafe());
if (cantPlaceMoreBombsAndSafe || shouldActivateRemote(_playerIndex))
{
startPushingRemoteButton();
}
}
}
// filled by serialize...
static size_t serializeSize=0;
static size_t serializeSize = 0;
size_t BotTree::serialize_size(void) {
if(serializeSize==0) {
uint8_t tmpBuffer[MEM_STREAM_BUFFER_SIZE];
serialize(tmpBuffer);
log_error("HARDCODED_RETRO_SERIALIZE_SIZE=SIZE_SER+%d*8\n",serializeSize);
}
assert(serializeSize!=0);
return serializeSize;
}
bool BotTree::serialize(void *data_) {
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
static memstream_t * stream=memstream_open(1);
assert(stream!=NULL);
memstream_rewind(stream);
assert(tree!=NULL);
tree->serialize(stream); // write to the stream
memstream_write(stream, &calculatedBestCellToPickUpBonus, sizeof(calculatedBestCellToPickUpBonus)); // write to the stream
memstream_write(stream, &_direction1FrameAgo, sizeof(_direction1FrameAgo)); // write to the stream
memstream_write(stream, &_direction2FramesAgo, sizeof(_direction2FramesAgo)); // write to the stream
memstream_write(stream, &_shiveringCounter, sizeof(_shiveringCounter)); // write to the stream
serializeSize=memstream_pos(stream);
memstream_rewind(stream);
memstream_read(stream, data_,serializeSize); // read from the stream
return true;
}
bool BotTree::unserialize(const void *data_) {
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
static memstream_t * stream=memstream_open(1);
assert(stream!=NULL);
memstream_rewind(stream);
memstream_write(stream, data_, serialize_size()); // write to the stream
memstream_rewind(stream);
assert(tree!=NULL);
tree->unserialize(stream);
memstream_read(stream, &calculatedBestCellToPickUpBonus, sizeof(calculatedBestCellToPickUpBonus)); // read from the stream
memstream_read(stream, &_direction1FrameAgo, sizeof(_direction1FrameAgo)); // write to the stream
memstream_read(stream, &_direction2FramesAgo, sizeof(_direction2FramesAgo)); // write to the stream
memstream_read(stream, &_shiveringCounter, sizeof(_shiveringCounter)); // write to the stream
return true;
size_t BotTree::serialize_size(void)
{
if (serializeSize == 0)
{
uint8_t tmpBuffer[MEM_STREAM_BUFFER_SIZE];
serialize(tmpBuffer);
log_error("HARDCODED_RETRO_SERIALIZE_SIZE=SIZE_SER+%d*8\n", serializeSize);
}
assert(serializeSize != 0);
return(serializeSize);
}
bool BotTree::serialize(void *data_)
{
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
static memstream_t *stream = memstream_open(1);
assert(stream != NULL);
memstream_rewind(stream);
assert(tree != NULL);
tree->serialize(stream); // write to the stream
memstream_write(stream, &calculatedBestCellToPickUpBonus, sizeof(calculatedBestCellToPickUpBonus)); // write to the stream
memstream_write(stream, &_direction1FrameAgo, sizeof(_direction1FrameAgo)); // write to the stream
memstream_write(stream, &_direction2FramesAgo, sizeof(_direction2FramesAgo)); // write to the stream
memstream_write(stream, &_shiveringCounter, sizeof(_shiveringCounter)); // write to the stream
serializeSize = memstream_pos(stream);
memstream_rewind(stream);
memstream_read(stream, data_, serializeSize); // read from the stream
return(true);
}
bool BotTree::unserialize(const void *data_)
{
memstream_set_buffer(buffer, MEM_STREAM_BUFFER_SIZE);
static memstream_t *stream = memstream_open(1);
assert(stream != NULL);
memstream_rewind(stream);
memstream_write(stream, data_, serialize_size()); // write to the stream
memstream_rewind(stream);
assert(tree != NULL);
tree->unserialize(stream);
memstream_read(stream, &calculatedBestCellToPickUpBonus, sizeof(calculatedBestCellToPickUpBonus)); // read from the stream
memstream_read(stream, &_direction1FrameAgo, sizeof(_direction1FrameAgo)); // write to the stream
memstream_read(stream, &_direction2FramesAgo, sizeof(_direction2FramesAgo)); // write to the stream
memstream_read(stream, &_shiveringCounter, sizeof(_shiveringCounter)); // write to the stream
return(true);
}

View File

@ -1,15 +1,16 @@
#include "bt.hpp"
#include "Bot.hpp"
#define MEM_STREAM_BUFFER_SIZE 64000
#define MEM_STREAM_BUFFER_SIZE 64000
class BotTree : public Bot {
public:
BotTree(int playerIndex);
size_t serialize_size(void);
bool serialize(void *data_);
bool unserialize(const void *data_);
void updateGrids();
void tick();
BotTree(int playerIndex);
size_t serialize_size(void);
bool serialize(void *data_);
bool unserialize(const void *data_);
void updateGrids();
void tick();
private:
bt::BehaviorTree * tree;
uint8_t buffer[MEM_STREAM_BUFFER_SIZE];
bt::BehaviorTree *tree;
uint8_t buffer[MEM_STREAM_BUFFER_SIZE];
};

View File

@ -3,303 +3,449 @@
#include "common.hpp"
#include "MrboomHelper.hpp"
#include <algorithm> // std::min
#define MAX_PIXELS_PER_FRAME 8
#ifndef DEBUG
#define NDEBUG
#endif
#include "assert.h"
#define MAX_PIXELS_PER_FRAME 8
#pragma pack(push, 1)
typedef struct bombInfo {
dd infojoueur;
dd countDown;
dd offsetCell;
dw flameSize;
dw remote;
dw adderX; //+1,0,-1
dw adderY; //+1,0,-1
dw offsetX; // 0 = middle
dw offsetY;
void cell(int cell) {
offsetCell=CELLX(cell)+CELLY(cell)*grid_size_x_with_padding;
}
int x() {
return CELLXWITHPADDING(offsetCell);
};
int y() {
return CELLYWITHPADDING(offsetCell);
};
int getPlayer() {
int bombPlayer=-1; //will return -1 on a end of level 2 bomb.
if (offsetof(struct Mem,j1)==infojoueur) bombPlayer=0;
if (offsetof(struct Mem,j2)==infojoueur) bombPlayer=1;
if (offsetof(struct Mem,j3)==infojoueur) bombPlayer=2;
if (offsetof(struct Mem,j4)==infojoueur) bombPlayer=3;
if (offsetof(struct Mem,j5)==infojoueur) bombPlayer=4;
if (offsetof(struct Mem,j6)==infojoueur) bombPlayer=5;
if (offsetof(struct Mem,j7)==infojoueur) bombPlayer=6;
if (offsetof(struct Mem,j8)==infojoueur) bombPlayer=7;
return bombPlayer;
}
typedef struct bombInfo
{
dd infojoueur;
dd countDown;
dd offsetCell;
dw flameSize;
dw remote;
dw adderX; //+1,0,-1
dw adderY; //+1,0,-1
dw offsetX; // 0 = middle
dw offsetY;
void cell(int cell)
{
offsetCell = CELLX(cell) + CELLY(cell) * grid_size_x_with_padding;
}
int x()
{
return(CELLXWITHPADDING(offsetCell));
};
int y()
{
return(CELLYWITHPADDING(offsetCell));
};
int getPlayer()
{
int bombPlayer = -1; //will return -1 on a end of level 2 bomb.
if (offsetof(struct Mem, j1) == infojoueur)
{
bombPlayer = 0;
}
if (offsetof(struct Mem, j2) == infojoueur)
{
bombPlayer = 1;
}
if (offsetof(struct Mem, j3) == infojoueur)
{
bombPlayer = 2;
}
if (offsetof(struct Mem, j4) == infojoueur)
{
bombPlayer = 3;
}
if (offsetof(struct Mem, j5) == infojoueur)
{
bombPlayer = 4;
}
if (offsetof(struct Mem, j6) == infojoueur)
{
bombPlayer = 5;
}
if (offsetof(struct Mem, j7) == infojoueur)
{
bombPlayer = 6;
}
if (offsetof(struct Mem, j8) == infojoueur)
{
bombPlayer = 7;
}
return(bombPlayer);
}
} bombInfo;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct travelCostGrid {
uint32_t travelCostGrid[grid_size_x][grid_size_y]; // safe to walk walking distance, TRAVELCOST_CANTGO if cant go, -7 to +8 if player is here...
uint32_t travelCostGridJumpLeftRight[grid_size_x][grid_size_y];
uint32_t travelCostGridJumpUpDown[grid_size_x][grid_size_y];
typedef struct travelCostGrid
{
uint32_t travelCostGrid[grid_size_x][grid_size_y]; // safe to walk walking distance, TRAVELCOST_CANTGO if cant go, -7 to +8 if player is here...
uint32_t travelCostGridJumpLeftRight[grid_size_x][grid_size_y];
uint32_t travelCostGridJumpUpDown[grid_size_x][grid_size_y];
uint32_t cost(int i,int j, int direction) const {
return std::min(jumpingCost(i,j,direction),travelCostGrid[i][j]); // min: to be able to jump on a flame and come back later using the walking way. (otherwise the comeback breaks the path)
}
bool wouldInvolveJumping(int i,int j, int direction) const {
return (jumpingCost(i,j,direction)<travelCostGrid[i][j]);
}
uint32_t cost(int i,int j) const {
return travelCostGrid[i][j];
}
uint32_t cost(int cell) const {
return cost(CELLX(cell),CELLY(cell));
}
void setWalkingCost(int cell,uint32_t cost) {
travelCostGrid[CELLX(cell)][CELLY(cell)]=cost;
}
void printCell(int i,int j) {
int lr=costLeftRight(i,j);
int up=costUpDown(i,j);
int w=cost(i,j);
uint32_t cost(int i, int j, int direction) const
{
return(std::min(jumpingCost(i, j, direction), travelCostGrid[i][j])); // min: to be able to jump on a flame and come back later using the walking way. (otherwise the comeback breaks the path)
}
if (TRAVELCOST_CANTGO!=w) {
log_debug(" %03d ",w);
} else {
bool wouldInvolveJumping(int i, int j, int direction) const
{
return(jumpingCost(i, j, direction) < travelCostGrid[i][j]);
}
if ((lr!=TRAVELCOST_CANTGO) || (up!=TRAVELCOST_CANTGO)) {
uint32_t cost(int i, int j) const
{
return(travelCostGrid[i][j]);
}
uint32_t cost(int cell) const
{
return(cost(CELLX(cell), CELLY(cell)));
}
if (TRAVELCOST_CANTGO!=lr) {
log_debug("%03d/",lr);
} else {
log_debug("---/");
}
if (TRAVELCOST_CANTGO!=up) {
log_debug("%03d ",up);
} else {
log_debug("--- ");
}
void setWalkingCost(int cell, uint32_t cost)
{
travelCostGrid[CELLX(cell)][CELLY(cell)] = cost;
}
} else {
log_debug(" --- ");
}
void printCell(int i, int j)
{
int lr = costLeftRight(i, j);
int up = costUpDown(i, j);
int w = cost(i, j);
}
}
if (TRAVELCOST_CANTGO != w)
{
log_debug(" %03d ", w);
}
else
{
if ((lr != TRAVELCOST_CANTGO) || (up != TRAVELCOST_CANTGO))
{
if (TRAVELCOST_CANTGO != lr)
{
log_debug("%03d/", lr);
}
else
{
log_debug("---/");
}
if (TRAVELCOST_CANTGO != up)
{
log_debug("%03d ", up);
}
else
{
log_debug("--- ");
}
}
else
{
log_debug(" --- ");
}
}
}
uint32_t jumpingCost(int i, int j, int direction) const
{
switch (direction)
{
case button_left:
return(travelCostGridJumpLeftRight[i][j]);
uint32_t jumpingCost(int i,int j,int direction) const {
switch (direction) {
case button_left:
return travelCostGridJumpLeftRight[i][j];
break;
case button_right:
return travelCostGridJumpLeftRight[i][j];
break;
case button_up:
return travelCostGridJumpUpDown[i][j];
break;
case button_down:
return travelCostGridJumpUpDown[i][j];
break;
default:
assert(0);
break;
}
return 0;
}
uint32_t jumpingCost(int cell,int direction) const {
int i=CELLX(cell);
int j=CELLY(cell);
return jumpingCost(i,j,direction);
}
uint32_t costLeftRight(int i,int j) const {
return jumpingCost(i,j,button_left);
}
break;
uint32_t costUpDown(int i,int j) const {
return jumpingCost(i,j,button_up);
}
case button_right:
return(travelCostGridJumpLeftRight[i][j]);
void setJumpingCost(int i,int j,uint32_t cost,int direction) {
switch (direction) {
case button_left:
travelCostGridJumpLeftRight[i][j]=cost;
break;
case button_right:
travelCostGridJumpLeftRight[i][j]=cost;
break;
case button_up:
travelCostGridJumpUpDown[i][j]=cost;
break;
case button_down:
travelCostGridJumpUpDown[i][j]=cost;
break;
default:
assert(0);
break;
}
}
break;
void setJumpingCost(int cell,uint32_t cost,int direction) {
int i=CELLX(cell);
int j=CELLY(cell);
return setJumpingCost(i,j,cost,direction);
}
case button_up:
return(travelCostGridJumpUpDown[i][j]);
bool canWalk(int i,int j) const {
return (travelCostGrid[i][j]!=TRAVELCOST_CANTGO);
}
bool canWalk(int cell) const {
return canWalk(CELLX(cell),CELLY(cell));
}
void init() {
for (int j=0; j<grid_size_y; j++)
{
for (int i=0; i<grid_size_x; i++) {
travelCostGrid[i][j]=TRAVELCOST_CANTGO;
travelCostGridJumpLeftRight[i][j]=TRAVELCOST_CANTGO;
travelCostGridJumpUpDown[i][j]=TRAVELCOST_CANTGO;
}
break;
}
}
void print() {
for (int i=0; i<grid_size_x; i++) {
log_debug("__%03d__ ",i);
}
log_debug("\n");
for (int j=0; j<grid_size_y; j++) {
for (int i=0; i<grid_size_x; i++) {
printCell(i,j);
}
log_debug("-%03d-",j);
log_debug("\n");
}
}
case button_down:
return(travelCostGridJumpUpDown[i][j]);
break;
default:
assert(0);
break;
}
return(0);
}
uint32_t jumpingCost(int cell, int direction) const
{
int i = CELLX(cell);
int j = CELLY(cell);
return(jumpingCost(i, j, direction));
}
uint32_t costLeftRight(int i, int j) const
{
return(jumpingCost(i, j, button_left));
}
uint32_t costUpDown(int i, int j) const
{
return(jumpingCost(i, j, button_up));
}
void setJumpingCost(int i, int j, uint32_t cost, int direction)
{
switch (direction)
{
case button_left:
travelCostGridJumpLeftRight[i][j] = cost;
break;
case button_right:
travelCostGridJumpLeftRight[i][j] = cost;
break;
case button_up:
travelCostGridJumpUpDown[i][j] = cost;
break;
case button_down:
travelCostGridJumpUpDown[i][j] = cost;
break;
default:
assert(0);
break;
}
}
void setJumpingCost(int cell, uint32_t cost, int direction)
{
int i = CELLX(cell);
int j = CELLY(cell);
return(setJumpingCost(i, j, cost, direction));
}
bool canWalk(int i, int j) const
{
return(travelCostGrid[i][j] != TRAVELCOST_CANTGO);
}
bool canWalk(int cell) const
{
return(canWalk(CELLX(cell), CELLY(cell)));
}
void init()
{
for (int j = 0; j < grid_size_y; j++)
{
for (int i = 0; i < grid_size_x; i++)
{
travelCostGrid[i][j] = TRAVELCOST_CANTGO;
travelCostGridJumpLeftRight[i][j] = TRAVELCOST_CANTGO;
travelCostGridJumpUpDown[i][j] = TRAVELCOST_CANTGO;
}
}
}
void print()
{
for (int i = 0; i < grid_size_x; i++)
{
log_debug("__%03d__ ", i);
}
log_debug("\n");
for (int j = 0; j < grid_size_y; j++)
{
for (int i = 0; i < grid_size_x; i++)
{
printCell(i, j);
}
log_debug("-%03d-", j);
log_debug("\n");
}
}
} travelCostGrid;
#pragma pack(pop)
enum Button howToGo(int player,int toX,int toY,const travelCostGrid& travelGrid,bool &shouldJump);
bool isPlayerFastestToCell(int player, int x,int y);
bool isSameTeamTwoFastestToCell(int x,int y);
enum Button howToGo(int player, int toX, int toY, const travelCostGrid& travelGrid, bool&shouldJump);
bool isPlayerFastestToCell(int player, int x, int y);
bool isSameTeamTwoFastestToCell(int x, int y);
typedef void (*FunctionWithBombInfo)(struct bombInfo *);
void iterateOnBombs(FunctionWithBombInfo f);
typedef void (*FunctionWithFlameDrawingHelpfulData)(int, int, int, int, uint32_t[grid_size_x][grid_size_y],bool[grid_size_x][grid_size_y],int&);
void drawBombFlames(int player, int cell, int flameSize, FunctionWithFlameDrawingHelpfulData f, uint32_t[grid_size_x][grid_size_y],bool[grid_size_x][grid_size_y],int&);
void updateBestExplosionGrid(int player, uint32_t bestExplosionsGrid[grid_size_x][grid_size_y], const travelCostGrid& travelGrid,const uint32_t flameGrid[grid_size_x][grid_size_y],const bool dangerGrid[grid_size_x][grid_size_y]);
void updateTravelGrid(int player, bool ignoreFlames, travelCostGrid& travelGrid,const uint32_t flameGrid[grid_size_x][grid_size_y],const bool dangerGrid[grid_size_x][grid_size_y]);
void updateFlameAndDangerGridsWithBombs(int player,uint32_t flameGrid[grid_size_x][grid_size_y],bool dangerGrid[grid_size_x][grid_size_y]);
typedef void (*FunctionWithFlameDrawingHelpfulData)(int, int, int, int, uint32_t[grid_size_x][grid_size_y], bool[grid_size_x][grid_size_y], int&);
void drawBombFlames(int player, int cell, int flameSize, FunctionWithFlameDrawingHelpfulData f, uint32_t[grid_size_x][grid_size_y], bool[grid_size_x][grid_size_y], int&);
void updateBestExplosionGrid(int player, uint32_t bestExplosionsGrid[grid_size_x][grid_size_y], const travelCostGrid& travelGrid, const uint32_t flameGrid[grid_size_x][grid_size_y], const bool dangerGrid[grid_size_x][grid_size_y]);
void updateTravelGrid(int player, bool ignoreFlames, travelCostGrid& travelGrid, const uint32_t flameGrid[grid_size_x][grid_size_y], const bool dangerGrid[grid_size_x][grid_size_y]);
void updateFlameAndDangerGridsWithBombs(int player, uint32_t flameGrid[grid_size_x][grid_size_y], bool dangerGrid[grid_size_x][grid_size_y]);
void updateDangerGridWithMonstersSickPlayersAndCulDeSacs(int player, bool dangerGrid[grid_size_x][grid_size_y]);
void updateDangerGridWithMonster4CellsTerritories(bool dangerGrid[grid_size_x][grid_size_y]);
bool flameInCell(int x,int y);
Bonus inline bonusInCell(int x,int y)
{
/*
;1 = bombe... (2,3,4) respirant... si c sup a 4; on est mort...
;5 = centre de bombe. de 5 a 11
;12 = ligne droite...
;19 = arrondie ligne droite vers la gauche...
;26 = arrondie ligne droite vers la droite
;33 = ligne verti
;40 arrondie verti vers le haut
;47-- bas
;54-- bonus bombe... de 54 a 63 (offset 144)
;64-- bonus flamme... de 64 a 73 (offset 144+320*16)
;74-- tete de mort de 74 a 83
;84-- bonus parre balle. de 84 a 93
;94-- bonus COEUR !!!
;104 -- bonus bombe retardement
;114 --- bonus pousseur
;124 --- patins a roulettes
;134 --- HORLOGE
;horloge
bonus_4 134
bonus_3 144,1,tribombe
bonus_6 154
;oeuf
bonus_5 193
*/
db z=m.truc2[x+y*grid_size_x_with_padding];
if ((z>=54) && (z<194))
{
if (z<64) return bonus_bomb;
if (z<74) return bonus_flame;
if (z<84) return bonus_skull;
if (z<94) return bonus_bulletproofjacket;
if (z<104) return bonus_heart;
if (z<114) return bonus_remote;
if (z<124) return bonus_push;
if (z<134) return bonus_roller;
if (z<144) return bonus_time;
if (z<154) return bonus_tribomb;
if (z<164) return bonus_banana;
return bonus_egg;
}
bool flameInCell(int x, int y);
return no_bonus;
Bonus inline bonusInCell(int x, int y)
{
/*
* ;1 = bombe... (2,3,4) respirant... si c sup a 4; on est mort...
* ;5 = centre de bombe. de 5 a 11
* ;12 = ligne droite...
* ;19 = arrondie ligne droite vers la gauche...
* ;26 = arrondie ligne droite vers la droite
* ;33 = ligne verti
* ;40 arrondie verti vers le haut
* ;47-- bas
* ;54-- bonus bombe... de 54 a 63 (offset 144)
* ;64-- bonus flamme... de 64 a 73 (offset 144+320*16)
* ;74-- tete de mort de 74 a 83
* ;84-- bonus parre balle. de 84 a 93
* ;94-- bonus COEUR !!!
* ;104 -- bonus bombe retardement
* ;114 --- bonus pousseur
* ;124 --- patins a roulettes
* ;134 --- HORLOGE
* ;horloge
* bonus_4 134
* bonus_3 144,1,tribombe
* bonus_6 154
* ;oeuf
* bonus_5 193
*/
db z = m.truc2[x + y * grid_size_x_with_padding];
if ((z >= 54) && (z < 194))
{
if (z < 64)
{
return(bonus_bomb);
}
if (z < 74)
{
return(bonus_flame);
}
if (z < 84)
{
return(bonus_skull);
}
if (z < 94)
{
return(bonus_bulletproofjacket);
}
if (z < 104)
{
return(bonus_heart);
}
if (z < 114)
{
return(bonus_remote);
}
if (z < 124)
{
return(bonus_push);
}
if (z < 134)
{
return(bonus_roller);
}
if (z < 144)
{
return(bonus_time);
}
if (z < 154)
{
return(bonus_tribomb);
}
if (z < 164)
{
return(bonus_banana);
}
return(bonus_egg);
}
return(no_bonus);
}
bool monsterInCell(int x,int y);
bool playerInCell(int x,int y);
bool enemyInCell(int player,int x,int y);
bool enemyAroundCell(int player,int x,int y);
bool isCellCulDeSac(int x,int y);
bool monsterInCell(int x, int y);
bool playerInCell(int x, int y);
bool enemyInCell(int player, int x, int y);
bool enemyAroundCell(int player, int x, int y);
bool isCellCulDeSac(int x, int y);
extern int lastBombGridUpdate;
extern struct bombInfo * bombsGrid[grid_size_x][grid_size_y]; // NULL if no bomb, pointer to the bomb in m.liste_bombe
extern struct bombInfo *bombsGrid[grid_size_x][grid_size_y]; // NULL if no bomb, pointer to the bomb in m.liste_bombe
static void updateBombGrid(struct bombInfo * bomb) {
bombsGrid[bomb->x()][bomb->y()]=bomb;
static void updateBombGrid(struct bombInfo *bomb)
{
bombsGrid[bomb->x()][bomb->y()] = bomb;
}
int inline updateBombGrid()
{
memset(bombsGrid, 0, sizeof(bombsGrid));
iterateOnBombs(updateBombGrid);
return frameNumber();
}
bool inline bombInCell(int x,int y)
{
if ((!lastBombGridUpdate) || (frameNumber()!=lastBombGridUpdate)) lastBombGridUpdate=updateBombGrid();
return (bombsGrid[x][y]!=NULL);
}
bool somethingThatWouldStopFlame(int x,int y);
bool inline mudbrickInCell(int x,int y)
{
db brickKind=m.truc[x+y*grid_size_x_with_padding];
return (brickKind==2);
memset(bombsGrid, 0, sizeof(bombsGrid));
iterateOnBombs(updateBombGrid);
return(frameNumber());
}
bool inline brickInCell(int x,int y)
bool inline bombInCell(int x, int y)
{
db brickKind=m.truc[x+y*grid_size_x_with_padding];
return ((brickKind==1) || ((brickKind>=3) && (brickKind<=11)));
if ((!lastBombGridUpdate) || (frameNumber() != lastBombGridUpdate))
{
lastBombGridUpdate = updateBombGrid();
}
return(bombsGrid[x][y] != NULL);
}
bool inline brickOrSkullBonus(int x,int y) {
if (brickInCell(x,y))
return true;
if (mudbrickInCell(x,y))
return true;
if (bonusInCell(x,y)==bonus_skull)
return true;
return false;
bool somethingThatWouldStopFlame(int x, int y);
bool inline mudbrickInCell(int x, int y)
{
db brickKind = m.truc[x + y * grid_size_x_with_padding];
return(brickKind == 2);
}
bool inline somethingThatIsNoTABombAndThatWouldStopPlayer(int x,int y) {
if (brickOrSkullBonus(x,y))
return true;
if (monsterInCell(x,y))
return true;
return false;
bool inline brickInCell(int x, int y)
{
db brickKind = m.truc[x + y * grid_size_x_with_padding];
return((brickKind == 1) || ((brickKind >= 3) && (brickKind <= 11)));
}
bool inline brickOrSkullBonus(int x, int y)
{
if (brickInCell(x, y))
{
return(true);
}
if (mudbrickInCell(x, y))
{
return(true);
}
if (bonusInCell(x, y) == bonus_skull)
{
return(true);
}
return(false);
}
bool inline somethingThatIsNoTABombAndThatWouldStopPlayer(int x, int y)
{
if (brickOrSkullBonus(x, y))
{
return(true);
}
if (monsterInCell(x, y))
{
return(true);
}
return(false);
}
void updateMonsterIsComingGrid(bool monsterIsComingGrid[NUMBER_OF_CELLS]);
bool canPlayerBeReachedByMonster(int player);
bool canPlayerReachEnemy(int player);

View File

@ -4,373 +4,485 @@
void addOneAIPlayer()
{
db * keys=m.total_t;
keys[64+5+m.nombre_de_dyna*7]=1;
keys[8*7+2]=1;
m.nb_ai_bombermen++;
db *keys = m.total_t;
keys[64 + 5 + m.nombre_de_dyna * 7] = 1;
keys[8 * 7 + 2] = 1;
m.nb_ai_bombermen++;
}
void addXAIPlayers(int x)
{
db * keys=m.total_t;
for (int i=0; i<x; i++) keys[64+5+i*7]=1;
keys[8*7+2]=1;
db *keys = m.total_t;
for (int i = 0; i < x; i++)
{
keys[64 + 5 + i * 7] = 1;
}
keys[8 * 7 + 2] = 1;
}
void pressStart()
{
db * keys=m.total_t;
keys[8*7]=1;
keys[8*7+2]=1;
db *keys = m.total_t;
keys[8 * 7] = 1;
keys[8 * 7 + 2] = 1;
}
void pressESC()
{
m.sortie=1;
m.sortie = 1;
}
bool isInTheApocalypse() {
return (m.in_the_apocalypse==1);
bool isInTheApocalypse()
{
return(m.in_the_apocalypse == 1);
}
bool hasRollers(int player) {
return (m.patineur[player]==1);
bool hasRollers(int player)
{
return(m.patineur[player] == 1);
}
bool hasRemote(int player) {
return m.j1[4+player*5];
bool hasRemote(int player)
{
return(m.j1[4 + player * 5]);
}
bool hasPush(int player) {
return (m.pousseur[player]==1);
bool hasPush(int player)
{
return(m.pousseur[player] == 1);
}
bool hasTriBomb(int player) {
return (m.tribombe[player]==1);
bool hasTriBomb(int player)
{
return(m.tribombe[player] == 1);
}
// Warning will be zero if less then 1
int pixelsPerFrame(int player) {
return CELLPIXELSSIZE/framesToCrossACell(player);
int pixelsPerFrame(int player)
{
return(CELLPIXELSSIZE / framesToCrossACell(player));
}
int framesToCrossACell(int player)
{
bool speed=hasSpeedDisease(player);
bool slow=hasSlowDisease(player);
if (hasRollers(player))
{
if (slow)
return (CELLPIXELSSIZE/2)*4; //32
if (speed)
return (CELLPIXELSSIZE/2)/4; //2
return CELLPIXELSSIZE/2; //8
}
bool speed = hasSpeedDisease(player);
bool slow = hasSlowDisease(player);
if (slow)
return CELLPIXELSSIZE*4; //64
if (speed)
return CELLPIXELSSIZE/4; //4
return CELLPIXELSSIZE; //16
if (hasRollers(player))
{
if (slow)
{
return((CELLPIXELSSIZE / 2) * 4); //32
}
if (speed)
{
return((CELLPIXELSSIZE / 2) / 4); //2
}
return(CELLPIXELSSIZE / 2); //8
}
if (slow)
{
return(CELLPIXELSSIZE * 4); //64
}
if (speed)
{
return(CELLPIXELSSIZE / 4); //4
}
return(CELLPIXELSSIZE); //16
}
int nbLives(int player) {
if (isAlive(player)) {
return (m.nombre_de_coups[player]+1);
} else {
return 0;
}
int nbLives(int player)
{
if (isAlive(player))
{
return(m.nombre_de_coups[player] + 1);
}
else
{
return(0);
}
}
bool isAlive(int player)
{
return (m.vie[player]==1);
return(m.vie[player] == 1);
}
bool isAIActiveForPlayer(int player)
{
return ((m.control_joueur[player]>=64) && (m.control_joueur[player]<=64*2));
return((m.control_joueur[player] >= 64) && (m.control_joueur[player] <= 64 * 2));
}
bool hasAnyDisease(int player) {
return (m.maladie[player*2]!=0);
bool hasAnyDisease(int player)
{
return(m.maladie[player * 2] != 0);
}
bool hasSlowDisease(int player) {
return (m.maladie[player*2]==2);
bool hasSlowDisease(int player)
{
return(m.maladie[player * 2] == 2);
}
bool hasSpeedDisease(int player) {
return (m.maladie[player*2]==1);
bool hasSpeedDisease(int player)
{
return(m.maladie[player * 2] == 1);
}
bool hasInvertedDisease(int player) {
return (m.maladie[player*2]==4);
bool hasInvertedDisease(int player)
{
return(m.maladie[player * 2] == 4);
}
bool hasDiarrheaDisease(int player) {
return (m.maladie[player*2]==3);
}
bool hasSmallBombDisease(int player) {
return (m.maladie[player*2]==6);
}
bool hasConstipationDisease(int player) {
return (m.maladie[player*2]==5);
bool hasDiarrheaDisease(int player)
{
return(m.maladie[player * 2] == 3);
}
void setDisease(int player, int disease, int duration) {
m.maladie[player*2]=disease;
m.maladie[player*2+1]=duration;
bool hasSmallBombDisease(int player)
{
return(m.maladie[player * 2] == 6);
}
bool hasConstipationDisease(int player)
{
return(m.maladie[player * 2] == 5);
}
void setDisease(int player, int disease, int duration)
{
m.maladie[player * 2] = disease;
m.maladie[player * 2 + 1] = duration;
}
int numberOfPlayers()
{
return m.nombre_de_dyna;
}
bool replay() {
return m.action_replay!=0;
return(m.nombre_de_dyna);
}
int level() {
if (replay()) return -1;
if (inTheMenu()) return -1;
return m.viseur_liste_terrain;
bool replay()
{
return(m.action_replay != 0);
}
int level()
{
if (replay())
{
return(-1);
}
if (inTheMenu())
{
return(-1);
}
return(m.viseur_liste_terrain);
}
void chooseLevel(int level)
{
m.viseur_liste_terrain=level;
m.viseur_liste_terrain = level;
}
bool inTheMenu() {
return((isGameActive()==false) && m.ordre=='S');
bool inTheMenu()
{
return((isGameActive() == false) && m.ordre == 'S');
}
bool isGameActive()
{
if ((m.ordre==1) && (m.ordre2==3))
return true;
return false;
if ((m.ordre == 1) && (m.ordre2 == 3))
{
return(true);
}
return(false);
}
bool isAboutToWin() {
return (m.attente_avant_med<100);
bool isAboutToWin()
{
return(m.attente_avant_med < 100);
}
int nbBombsLeft(int player)
{
if (m.nombre_de_vbl_avant_le_droit_de_poser_bombe)
return 0;
if (hasConstipationDisease(player))
return 0;
if (isAboutToWin())
return 0;
return m.j1[player*5]; //nb of bombs
if (m.nombre_de_vbl_avant_le_droit_de_poser_bombe)
{
return(0);
}
if (hasConstipationDisease(player))
{
return(0);
}
if (isAboutToWin())
{
return(0);
}
return(m.j1[player * 5]); //nb of bombs
}
void activeApocalypse()
{
m.temps=2;
m.temps = 2;
}
int invincibility(int player) {
return m.invinsible[player];
int invincibility(int player)
{
return(m.invinsible[player]);
}
void activeCheatMode()
{
log_info("activeCheatMode\n");
m.temps=816;
for (db i=0; i<nb_dyna; i++)
{
// setDisease(i,3,1000); Diarrhea
/*
if (i>= m.nombre_de_dyna)
m.nombre_de_coups[i]=1; //number of lifes
else
m.nombre_de_coups[i]=99;
*/
log_info("activeCheatMode\n");
m.temps = 816;
for (db i = 0; i < nb_dyna; i++)
{
// setDisease(i,3,1000); Diarrhea
if (i< m.nombre_de_dyna) {
m.j1[i*5]=1; //nb of bombs
//m.j1[1+i*5]=5; // power of bombs
m.j1[4+i*5]=1; // remote
m.pousseur[i]=1; // bomb pusher
m.lapipipino[i]=1;
m.nombre_de_coups[i]++;
}
}
setNoMonsterMode(true);
/*
* if (i>= m.nombre_de_dyna)
* m.nombre_de_coups[i]=1; //number of lifes
* else
* m.nombre_de_coups[i]=99;
*/
if (i < m.nombre_de_dyna)
{
m.j1[i * 5] = 1; //nb of bombs
//m.j1[1+i*5]=5; // power of bombs
m.j1[4 + i * 5] = 1; // remote
m.pousseur[i] = 1; // bomb pusher
m.lapipipino[i] = 1;
m.nombre_de_coups[i]++;
}
}
setNoMonsterMode(true);
}
void setNoMonsterMode(bool on)
{
m.nomonster=on;
m.nomonster = on;
}
bool bonusPlayerWouldLike(int player,enum Bonus bonus)
bool bonusPlayerWouldLike(int player, enum Bonus bonus)
{
switch (bonus)
{
case no_bonus:
case bonus_skull:
case bonus_time:
return false;
case bonus_roller:
return (hasRollers(player)==false);
case bonus_remote:
return (hasRemote(player)==false);
case bonus_tribomb:
return false;
switch (bonus)
{
case no_bonus:
case bonus_skull:
case bonus_time:
return(false);
case bonus_roller:
return(hasRollers(player) == false);
case bonus_remote:
return(hasRemote(player) == false);
case bonus_tribomb:
return(false);
// return (hasTriBomb(player)==false);
case bonus_push:
return (hasPush(player)==false);
case bonus_egg:
return (hasKangaroo(player)==false);
default:
break;
}
return true;
case bonus_push:
return(hasPush(player) == false);
case bonus_egg:
return(hasKangaroo(player) == false);
default:
break;
}
return(true);
}
void setFrameNumber(int frame) {
m.changement=frame;
void setFrameNumber(int frame)
{
m.changement = frame;
}
int flameSize(int player)
{
if (hasSmallBombDisease(player))
return 1;
return m.j1[1+player*5];
if (hasSmallBombDisease(player))
{
return(1);
}
return(m.j1[1 + player * 5]);
}
void setTeamMode(int teamMode) {
m.team3_sauve=teamMode;
void setTeamMode(int teamMode)
{
m.team3_sauve = teamMode;
}
int teamMode() {
return m.team3_sauve;
int teamMode()
{
return(m.team3_sauve);
}
void setAutofire(bool on) {
if (on) {
m.autofire=1;
} else {
m.autofire=0;
}
void setAutofire(bool on)
{
if (on)
{
m.autofire = 1;
}
else
{
m.autofire = 0;
}
}
bool autofire() {
return (m.autofire==1);
bool autofire()
{
return(m.autofire == 1);
}
int xPlayer(int player) {
return (m.donnee[player]+DELTA_X)/CELLPIXELSSIZE;
}
int yPlayer(int player) {
return (m.donnee[nb_dyna+player]+DELTA_Y)/CELLPIXELSSIZE;
int xPlayer(int player)
{
return((m.donnee[player] + DELTA_X) / CELLPIXELSSIZE);
}
int cellPlayer(int player) {
return (xPlayer(player)+yPlayer(player)*grid_size_x);
int yPlayer(int player)
{
return((m.donnee[nb_dyna + player] + DELTA_Y) / CELLPIXELSSIZE);
}
bool tracesDecisions(int player) {
return(debugTracesPlayer(player) && (traceMask & DEBUG_MASK_BOTTREEDECISIONS));
int cellPlayer(int player)
{
return(xPlayer(player) + yPlayer(player) * grid_size_x);
}
bool isInMiddleOfCell(int player) {
int step=pixelsPerFrame(player);
assert(step<=MAX_PIXELS_PER_FRAME);
int x=GETXPIXELSTOCENTEROFCELL(player);
int y=GETYPIXELSTOCENTEROFCELL(player);
if (step<1)
return ((!x) && (!y));
return ((x>=-step/2) && (x<=step/2) && (y<=step/2) && (y>=-step/2));
bool tracesDecisions(int player)
{
return(debugTracesPlayer(player) && (traceMask & DEBUG_MASK_BOTTREEDECISIONS));
}
int dangerousCellForMonster(int player) {
int cell=cellPlayer(player);
int index=m.viseur_change_in[player]/4;
index--;
if (index<0) {
index=15;
}
switch (m.changeiny[index]) {
case 0:
return cell+grid_size_x;
case 8:
return cell+1;
case 16:
return cell-1;
case 24:
return cell-grid_size_x;
}
assert(0);
return 0;
bool isInMiddleOfCell(int player)
{
int step = pixelsPerFrame(player);
assert(step <= MAX_PIXELS_PER_FRAME);
int x = GETXPIXELSTOCENTEROFCELL(player);
int y = GETYPIXELSTOCENTEROFCELL(player);
if (step < 1)
{
return((!x) && (!y));
}
return((x >= -step / 2) && (x <= step / 2) && (y <= step / 2) && (y >= -step / 2));
}
int victories(int player) {
int mode = teamMode();
switch (mode)
{
case 0:
return m.victoires[player];
break;
case 1: // color mode
return m.victoires[player/2];
break;
int dangerousCellForMonster(int player)
{
int cell = cellPlayer(player);
int index = m.viseur_change_in[player] / 4;
case 2: // sex mode
return m.victoires[player%2];
break;
default:
assert(0);
break;
}
return 0;
}
void pauseGameButton() {
if (m.pauseur2) {
m.pauseur2=0;
index--;
if (index < 0)
{
index = 15;
}
switch (m.changeiny[index])
{
case 0:
return(cell + grid_size_x);
} else {
m.pauseur2=4;
}
case 8:
return(cell + 1);
case 16:
return(cell - 1);
case 24:
return(cell - grid_size_x);
}
assert(0);
return(0);
}
bool isGamePaused() {
return m.pauseur2;
int victories(int player)
{
int mode = teamMode();
switch (mode)
{
case 0:
return(m.victoires[player]);
break;
case 1: // color mode
return(m.victoires[player / 2]);
break;
case 2: // sex mode
return(m.victoires[player % 2]);
break;
default:
assert(0);
break;
}
return(0);
}
bool isSuicideOK(int player) {
int myTeam=teamOfPlayer(player);
int nbLivesEnemies=0;
int nbLivesFriends=0;
for (int i=0; i<numberOfPlayers(); i++) {
if (myTeam==teamOfPlayer(i)) {
nbLivesFriends+=nbLives(i);
if (invincibility(i)) nbLivesFriends++;
}
if (myTeam!=teamOfPlayer(i)) {
nbLivesEnemies+=nbLives(i);
if (invincibility(i)) nbLivesEnemies++;
}
}
return ((nbLivesFriends>1) && (nbLivesEnemies==1));
void pauseGameButton()
{
if (m.pauseur2)
{
m.pauseur2 = 0;
}
else
{
m.pauseur2 = 4;
}
}
bool someHumanPlayersAlive() {
for (int i=0; i<numberOfPlayers(); i++) {
if (isAIActiveForPlayer(i)==false) {
if (isAlive(i)) return true;
}
}
return false;
bool isGamePaused()
{
return(m.pauseur2);
}
bool isSuicideOK(int player)
{
int myTeam = teamOfPlayer(player);
int nbLivesEnemies = 0;
int nbLivesFriends = 0;
for (int i = 0; i < numberOfPlayers(); i++)
{
if (myTeam == teamOfPlayer(i))
{
nbLivesFriends += nbLives(i);
if (invincibility(i))
{
nbLivesFriends++;
}
}
if (myTeam != teamOfPlayer(i))
{
nbLivesEnemies += nbLives(i);
if (invincibility(i))
{
nbLivesEnemies++;
}
}
}
return((nbLivesFriends > 1) && (nbLivesEnemies == 1));
}
bool someHumanPlayersAlive()
{
for (int i = 0; i < numberOfPlayers(); i++)
{
if (isAIActiveForPlayer(i) == false)
{
if (isAlive(i))
{
return(true);
}
}
}
return(false);
}

View File

@ -2,43 +2,48 @@
#include <stdint.h>
#include "mrboom.h"
#include "common.hpp"
#ifndef DEBUG
#define NDEBUG
#endif
#include "assert.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DELTA_X 3
#define DELTA_Y 14
#define COUNTDOWN_DURATON 256
#define CELLPIXELSSIZE 16
#define grid_size_x_with_padding (32)
#define grid_size_x (grid_size_x_with_padding-13)
#define grid_size_y (13)
#define NUMBER_OF_CELLS (grid_size_x*grid_size_y)
#define GETXPIXELSTOCENTEROFCELL(player) (-7+((m.donnee[player]+DELTA_X)%CELLPIXELSSIZE))
#define GETYPIXELSTOCENTEROFCELL(player) (-7+((m.donnee[nb_dyna+player]+DELTA_Y)%CELLPIXELSSIZE))
#define CELLINDEX(cellx,celly) (((celly)*grid_size_x)+(cellx))
#define CELLX(cell) (cell%grid_size_x)
#define CELLY(cell) (cell/grid_size_x)
#define CELLXWITHPADDING(cell) (cell%grid_size_x_with_padding)
#define CELLYWITHPADDING(cell) (cell/grid_size_x_with_padding)
#define TRAVELCOST_CANTGO 9999
#define FLAME_DURATION (16*5+6*4*2)
#define MAX_PIXELS_PER_FRAME 8
#define DELTA_X 3
#define DELTA_Y 14
#define COUNTDOWN_DURATON 256
#define CELLPIXELSSIZE 16
#define grid_size_x_with_padding (32)
#define grid_size_x (grid_size_x_with_padding - 13)
#define grid_size_y (13)
#define NUMBER_OF_CELLS (grid_size_x * grid_size_y)
#define GETXPIXELSTOCENTEROFCELL(player) (-7 + ((m.donnee[player] + DELTA_X) % CELLPIXELSSIZE))
#define GETYPIXELSTOCENTEROFCELL(player) (-7 + ((m.donnee[nb_dyna + player] + DELTA_Y) % CELLPIXELSSIZE))
#define CELLINDEX(cellx, celly) (((celly) * grid_size_x) + (cellx))
#define CELLX(cell) (cell % grid_size_x)
#define CELLY(cell) (cell / grid_size_x)
#define CELLXWITHPADDING(cell) (cell % grid_size_x_with_padding)
#define CELLYWITHPADDING(cell) (cell / grid_size_x_with_padding)
#define TRAVELCOST_CANTGO 9999
#define FLAME_DURATION (16 * 5 + 6 * 4 * 2)
#define MAX_PIXELS_PER_FRAME 8
enum Bonus {
no_bonus,
bonus_bomb,
bonus_flame,
bonus_skull,
bonus_bulletproofjacket,
bonus_heart,
bonus_remote,
bonus_push,
bonus_roller,
bonus_time,
bonus_tribomb,
bonus_banana,
bonus_egg
enum Bonus
{
no_bonus,
bonus_bomb,
bonus_flame,
bonus_skull,
bonus_bulletproofjacket,
bonus_heart,
bonus_remote,
bonus_push,
bonus_roller,
bonus_time,
bonus_tribomb,
bonus_banana,
bonus_egg
};
bool someHumanPlayersAlive();
@ -49,9 +54,12 @@ void addOneAIPlayer();
void addXAIPlayers(int x);
void pressStart();
void pressESC();
bool inline hasKangaroo(int player) {
return (m.lapipipino[player]==1);
bool inline hasKangaroo(int player)
{
return(m.lapipipino[player] == 1);
}
bool hasRemote(int player);
bool hasRollers(int player);
bool hasPush(int player);
@ -65,7 +73,7 @@ bool hasSmallBombDisease(int player);
bool hasConstipationDisease(int player);
void setDisease(int player, int disease, int duration);
int nbBombsLeft(int player);
bool bonusPlayerWouldLike(int player,enum Bonus bonus);
bool bonusPlayerWouldLike(int player, enum Bonus bonus);
int numberOfPlayers();
bool inTheMenu();
bool isGameActive();
@ -76,9 +84,12 @@ void setNoMonsterMode(bool on);
int invincibility(int player);
int framesToCrossACell(int player);
int pixelsPerFrame(int player);
int inline frameNumber() {
return m.changement;
int inline frameNumber()
{
return(m.changement);
}
void setFrameNumber(int frame);
int flameSize(int player);
void chooseLevel(int level);
@ -97,52 +108,60 @@ bool tracesDecisions(int player);
bool isInMiddleOfCell(int player);
int dangerousCellForMonster(int player);
int victories(int player);
int inline getAdderX(int player) {
return GETXPIXELSTOCENTEROFCELL(player)*framesToCrossACell(player)/CELLPIXELSSIZE;
int inline getAdderX(int player)
{
return(GETXPIXELSTOCENTEROFCELL(player) * framesToCrossACell(player) / CELLPIXELSSIZE);
}
int inline getAdderY(int player) {
return GETYPIXELSTOCENTEROFCELL(player)*framesToCrossACell(player)/CELLPIXELSSIZE;
int inline getAdderY(int player)
{
return(GETYPIXELSTOCENTEROFCELL(player) * framesToCrossACell(player) / CELLPIXELSSIZE);
}
bool isSuicideOK(int player);
int nbLives(int player);
enum playerKind
{
player_team1 = 1,
player_team2 = 2,
player_team3 = 4,
player_team4 = 8,
player_team5 = 16,
player_team6 = 32,
player_team7 = 64,
player_team8 = 128,
monster_team = 256
player_team1 = 1,
player_team2 = 2,
player_team3 = 4,
player_team4 = 8,
player_team5 = 16,
player_team6 = 32,
player_team7 = 64,
player_team8 = 128,
monster_team = 256
};
enum playerKind inline teamOfPlayer(int player)
{
enum playerKind result=monster_team;
int mode = teamMode();
enum playerKind result = monster_team;
int mode = teamMode();
switch (mode)
{
case 0:
result=static_cast<playerKind>(1 << player);
break;
case 1: // color mode
result=static_cast<playerKind>(1 << player/2);
break;
switch (mode)
{
case 0:
result = static_cast <playerKind>(1 << player);
break;
case 2: // sex mode
result=static_cast<playerKind>(1 << player%2);
break;
default:
assert(0);
break;
}
return result;
case 1: // color mode
result = static_cast <playerKind>(1 << player / 2);
break;
case 2: // sex mode
result = static_cast <playerKind>(1 << player % 2);
break;
default:
assert(0);
break;
}
return(result);
}
#ifdef __cplusplus
}
#endif

View File

@ -1,11 +1,12 @@
![alt tag](../tests/screenshots/mrboom-0.gif)
![alt tag](../tests/screenshots/mrboom-1.gif)
![alt tag](../tests/screenshots/mrboom-2.gif)
![alt tag](../tests/screenshots/mrboom-3.gif)
![alt tag](../tests/screenshots/mrboom-4.gif)
![alt tag](../tests/screenshots/mrboom-5.gif)
![alt tag](../tests/screenshots/mrboom-6.gif)
![alt tag](../tests/screenshots/mrboom-7.gif)
![alt tag](../ tests / screenshots / mrboom - 0.gif)
![alt tag](../ tests / screenshots / mrboom - 1.gif)
![alt tag](../ tests / screenshots / mrboom - 2.gif)
![alt tag](../ tests / screenshots / mrboom - 3.gif)
![alt tag](../ tests / screenshots / mrboom - 4.gif)
![alt tag](../ tests / screenshots / mrboom - 5.gif)
![alt tag](../ tests / screenshots / mrboom - 6.gif)
![alt tag](../ tests / screenshots / mrboom - 7.gif)
![alt tag](bt.png)
Using a c++98 port of arvidsson's [behavior tree library](https://github.com/arvidsson/bt).
Using a c++ 98 port of arvidsson 's [behavior tree library](https://github.com/arvidsson/bt).

View File

@ -8,4 +8,3 @@
// composites
#include "bt/composites/Selector.hpp"
#include "bt/composites/Sequence.hpp"

View File

@ -4,35 +4,40 @@
namespace bt
{
class BehaviorTree : public Node
{
public:
BehaviorTree() {
root = NULL;
}
BehaviorTree(Node * rootNode) {
root = rootNode;
}
BehaviorTree()
{
root = NULL;
}
Status Update() {
return root->Tick();
}
BehaviorTree(Node *rootNode)
{
root = rootNode;
}
void SetRoot(Node * node) {
root = node;
}
Status Update()
{
return(root->Tick());
}
void serialize(memstream_t * stream) {
root->serialize(stream);
}
void SetRoot(Node *node)
{
root = node;
}
void unserialize(memstream_t * stream) {
root->unserialize(stream);
}
void serialize(memstream_t *stream)
{
root->serialize(stream);
}
void unserialize(memstream_t *stream)
{
root->unserialize(stream);
}
private:
Node * root;
Node *root;
};
}

View File

@ -4,49 +4,60 @@
namespace bt
{
class Composite : public Node
{
public:
Composite() {
index = 0;
}
virtual ~Composite() {
}
Composite()
{
index = 0;
}
void AddChild(Node * child) {
children.push_back(child);
}
bool HasNoChildren() const {
return children.empty();
}
int GetIndex() const {
return index;
}
virtual ~Composite()
{
}
void serialize(memstream_t * stream) {
// TOFIX big endian
Node::serialize(stream);
memstream_write(stream, &index, sizeof(index));
for (int i=0; i<(signed)children.size(); i++) {
bt::Node * child = children.at(i);
child->serialize(stream);
}
}
void unserialize(memstream_t * stream) {
// TOFIX big endian
Node::unserialize(stream);
memstream_read(stream, &index, sizeof(index));
for (int i=0; i<(signed)children.size(); i++) {
bt::Node * child = children.at(i);
child->unserialize(stream);
}
}
void AddChild(Node *child)
{
children.push_back(child);
}
bool HasNoChildren() const
{
return(children.empty());
}
int GetIndex() const
{
return(index);
}
void serialize(memstream_t *stream)
{
// TOFIX big endian
Node::serialize(stream);
memstream_write(stream, &index, sizeof(index));
for (int i = 0; i < (signed)children.size(); i++)
{
bt::Node *child = children.at(i);
child->serialize(stream);
}
}
void unserialize(memstream_t *stream)
{
// TOFIX big endian
Node::unserialize(stream);
memstream_read(stream, &index, sizeof(index));
for (int i = 0; i < (signed)children.size(); i++)
{
bt::Node *child = children.at(i);
child->unserialize(stream);
}
}
protected:
std::vector<Node *> children;
uint8_t index;
std::vector <Node *> children;
uint8_t index;
};
}

View File

@ -6,75 +6,97 @@
namespace bt
{
enum Status
{
Invalid,
Success,
Failure,
Running
Invalid,
Success,
Failure,
Running
};
class Node
{
public:
Node() {
status = Invalid;
}
Node()
{
status = Invalid;
}
virtual ~Node() {
}
virtual ~Node()
{
}
virtual Status Update() = 0;
virtual void Initialize() {
}
virtual void Terminate(Status s) {
}
virtual Status Update() = 0;
virtual void serialize(memstream_t * stream) {
uint8_t s=(uint8_t) status;
memstream_write(stream, &s, sizeof(s));
}
virtual void Initialize()
{
}
virtual void unserialize(memstream_t * stream) {
uint8_t s;
memstream_read(stream, &s, sizeof(s));
status=bt::Status(s);
}
virtual void Terminate(Status s)
{
}
Status Tick()
{
if (status != Running)
Initialize();
virtual void serialize(memstream_t *stream)
{
uint8_t s = (uint8_t)status;
status = Update();
memstream_write(stream, &s, sizeof(s));
}
if (status != Running)
Terminate(status);
virtual void unserialize(memstream_t *stream)
{
uint8_t s;
return status;
}
memstream_read(stream, &s, sizeof(s));
status = bt::Status(s);
}
Status Tick()
{
if (status != Running)
{
Initialize();
}
status = Update();
if (status != Running)
{
Terminate(status);
}
return(status);
}
bool IsSuccess() const
{
return(status == Success);
}
bool IsFailure() const
{
return(status == Failure);
}
bool IsRunning() const
{
return(status == Running);
}
bool IsTerminated() const
{
return(IsSuccess() || IsFailure());
}
void Reset()
{
status = Invalid;
}
bool IsSuccess() const {
return status == Success;
}
bool IsFailure() const {
return status == Failure;
}
bool IsRunning() const {
return status == Running;
}
bool IsTerminated() const {
return IsSuccess() || IsFailure();
}
void Reset() {
status = Invalid;
}
protected:
Status status;
Status status;
};
//using Nodes = std::vector<Node *>;
}

View File

@ -4,42 +4,45 @@
namespace bt
{
/*
The Selector composite ticks each child node in order.
If a child succeeds or runs, the sequence returns the same status.
In the next tick, it will try to run each child in order again.
If all children fails, only then does the selector fail.
* The Selector composite ticks each child node in order.
* If a child succeeds or runs, the sequence returns the same status.
* In the next tick, it will try to run each child in order again.
* If all children fails, only then does the selector fail.
*/
class Selector : public Composite
{
public:
void Initialize()
{
index = 0;
}
void Initialize()
{
index = 0;
}
Status Update()
{
if (HasNoChildren())
return Success;
Status Update()
{
if (HasNoChildren())
{
return(Success);
}
// Keep going until a child behavior says it's running.
while (1)
{
bt::Node * child = children.at(index);
bt::Status status = child->Tick();
// Keep going until a child behavior says it's running.
while (1)
{
bt::Node * child = children.at(index);
bt::Status status = child->Tick();
// If the child succeeds, or keeps running, do the same.
if (status != Failure)
return status;
// Hit the end of the array, it didn't end well...
if (++index == (signed)children.size())
return Failure;
}
}
// If the child succeeds, or keeps running, do the same.
if (status != Failure)
{
return(status);
}
// Hit the end of the array, it didn't end well...
if (++index == (signed)children.size())
{
return(Failure);
}
}
}
};
}

View File

@ -4,41 +4,45 @@
namespace bt
{
/*
The Sequence composite ticks each child node in order.
If a child fails or runs, the sequence returns the same status.
In the next tick, it will try to run each child in order again.
If all children succeeds, only then does the sequence succeed.
* The Sequence composite ticks each child node in order.
* If a child fails or runs, the sequence returns the same status.
* In the next tick, it will try to run each child in order again.
* If all children succeeds, only then does the sequence succeed.
*/
class Sequence : public Composite
{
public:
void Initialize()
{
index = 0;
}
void Initialize()
{
index = 0;
}
Status Update()
{
if (HasNoChildren())
return Success;
Status Update()
{
if (HasNoChildren())
{
return(Success);
}
// Keep going until a child behavior says it's running.
while (1)
{
bt::Node * child = children.at(index);
bt::Status status = child->Tick();
// Keep going until a child behavior says it's running.
while (1)
{
bt::Node * child = children.at(index);
bt::Status status = child->Tick();
// If the child fails, or keeps running, do the same.
if (status != Success)
return status;
// If the child fails, or keeps running, do the same.
if (status != Success)
{
return(status);
}
// Hit the end of the array, job done!
if (++index == (signed)children.size())
return Success;
}
}
// Hit the end of the array, job done!
if (++index == (signed)children.size())
{
return(Success);
}
}
}
};
}

View File

@ -7,71 +7,74 @@
#ifdef __cplusplus
extern "C" {
#endif
#define GAME_NAME "Mr.Boom"
#define GAME_VERSION "4.1"
#define PATH_MAX_LENGTH 256
#define WIDTH 320
#define HEIGHT 200
#define NB_COLORS_PALETTE 256
#define nb_dyna 8
#define GAME_NAME "Mr.Boom"
#define GAME_VERSION "4.1"
#define PATH_MAX_LENGTH 256
#define WIDTH 320
#define HEIGHT 200
#define NB_COLORS_PALETTE 256
#define nb_dyna 8
class BotTree;
extern BotTree* tree[nb_dyna];
enum Button {
button_b,
button_y,
button_select,
button_start,
button_up,
button_down,
button_left,
button_right,
button_a,
button_x,
button_l,
button_r,
button_error
extern BotTree *tree[nb_dyna];
enum Button
{
button_b,
button_y,
button_select,
button_start,
button_up,
button_down,
button_left,
button_right,
button_a,
button_x,
button_l,
button_r,
button_error
};
#define FIRST_RW_VARIABLE replayer_saver
#define FIRST_RW_VARIABLE_DB nosetjmp
#define NB_DD_VARIABLES_IN_RW_SEGMENT (offsetof(struct Mem,FIRST_RW_VARIABLE_DB)-offsetof(struct Mem,FIRST_RW_VARIABLE))/4
#define FIRST_RO_VARIABLE master
#define SIZE_RO_SEGMENT offsetof(struct Mem,FIRST_RW_VARIABLE)-offsetof(struct Mem,FIRST_RO_VARIABLE)
#define SIZE_SER offsetof(struct Mem,selectorsPointer)-offsetof(struct Mem,FIRST_RW_VARIABLE)
#define FIRST_RW_VARIABLE replayer_saver
#define FIRST_RW_VARIABLE_DB nosetjmp
#define NB_DD_VARIABLES_IN_RW_SEGMENT (offsetof(struct Mem, FIRST_RW_VARIABLE_DB) - offsetof(struct Mem, FIRST_RW_VARIABLE)) / 4
#define FIRST_RO_VARIABLE master
#define SIZE_RO_SEGMENT offsetof(struct Mem, FIRST_RW_VARIABLE) - offsetof(struct Mem, FIRST_RO_VARIABLE)
#define SIZE_SER offsetof(struct Mem, selectorsPointer) - offsetof(struct Mem, FIRST_RW_VARIABLE)
bool mrboom_init();
void mrboom_deinit(void);
void mrboom_update_input(int keyid,int playerNumber,int state,bool isIA);
void mrboom_update_input(int keyid, int playerNumber, int state, bool isIA);
void mrboom_sound(void);
bool mrboom_debug_state_failed();
void mrboom_reset_special_keys();
void mrboom_tick_ai();
void mrboom_deal_with_autofire();
bool debugTracesPlayer(int player);
extern bool cheatMode;
#ifdef DEBUG
enum BotState { goingNowhere, goingSafe, goingBonus, goingBomb };
extern BotState botStates[nb_dyna];
extern int walkingToCell[nb_dyna];
extern int walkingToCell[nb_dyna];
#endif
#ifdef __LIBRETRO__
#define FPS_RATE 60.0
#define SAMPLE_RATE 48000.0f
#define FPS_RATE 60.0
#define SAMPLE_RATE 48000.0f
extern int16_t *frame_sample_buf;
extern uint32_t num_samples_per_frame;
extern retro_audio_sample_batch_t audio_batch_cb;
void audio_callback(void);
#define DEFAULT_TRACE_MAX 0
#define DEFAULT_TRACE_MAX 0
#endif
#ifdef __LIBSDL2__
extern int sdl2_fx_volume;
extern int sdl2_fx_volume;
extern bool music;
#define DEFAULT_SDL2_FX_VOLUME 4
#define DEFAULT_TRACE_MAX 1 | DEBUG_MASK_GRIDS
#define DEFAULT_SDL2_FX_VOLUME 4
#define DEFAULT_TRACE_MAX 1 | DEBUG_MASK_GRIDS
#endif
#define DEBUG_SDL2 1024
#define DEBUG_MASK_BOTTREEDECISIONS 512
#define DEBUG_MASK_GRIDS 256
#define DEBUG_SDL2 1024
#define DEBUG_MASK_BOTTREEDECISIONS 512
#define DEBUG_MASK_GRIDS 256
extern int traceMask;
#ifdef __cplusplus
}

2209
libretro.h

File diff suppressed because it is too large Load Diff

557887
mrboom.c

File diff suppressed because it is too large Load Diff

6152
mrboom.h

File diff suppressed because it is too large Load Diff

676
retro.cpp
View File

@ -9,227 +9,235 @@
static uint32_t *frame_buf;
static struct retro_log_callback logging;
retro_log_printf_t log_cb;
static char retro_save_directory[4096];
static char retro_base_directory[4096];
retro_log_printf_t log_cb;
static char retro_save_directory[4096];
static char retro_base_directory[4096];
static retro_video_refresh_t video_cb;
static retro_audio_sample_t audio_cb;
static retro_environment_t environ_cb;
static retro_input_poll_t input_poll_cb;
static retro_input_state_t input_state_cb;
static retro_audio_sample_t audio_cb;
static retro_environment_t environ_cb;
static retro_input_poll_t input_poll_cb;
static retro_input_state_t input_state_cb;
// Global core options
static const struct retro_variable var_mrboom_nomonster = { "mrboom-nomonster", "Monsters; ON|OFF" };
static const struct retro_variable var_mrboom_teammode = { "mrboom-teammode", "Team mode; Selfie|Color|Sex" };
static const struct retro_variable var_mrboom_autofire = { "mrboom-autofire", "Drop bomb autofire; OFF|ON" };
static const struct retro_variable var_mrboom_teammode = { "mrboom-teammode", "Team mode; Selfie|Color|Sex" };
static const struct retro_variable var_mrboom_autofire = { "mrboom-autofire", "Drop bomb autofire; OFF|ON" };
static const struct retro_variable var_empty = { NULL, NULL };
// joypads
#define DESC_NUM_PORTS(desc) ((desc)->port_max - (desc)->port_min + 1)
#define DESC_NUM_INDICES(desc) ((desc)->index_max - (desc)->index_min + 1)
#define DESC_NUM_IDS(desc) ((desc)->id_max - (desc)->id_min + 1)
#define DESC_NUM_PORTS(desc) ((desc)->port_max - (desc)->port_min + 1)
#define DESC_NUM_INDICES(desc) ((desc)->index_max - (desc)->index_min + 1)
#define DESC_NUM_IDS(desc) ((desc)->id_max - (desc)->id_min + 1)
#define DESC_OFFSET(desc, port, index, id) ( \
port * ((desc)->index_max - (desc)->index_min + 1) * ((desc)->id_max - (desc)->id_min + 1) + \
index * ((desc)->id_max - (desc)->id_min + 1) + \
id \
)
#define DESC_OFFSET(desc, port, index, id) ( \
port * ((desc)->index_max - (desc)->index_min + 1) * ((desc)->id_max - (desc)->id_min + 1) + \
index * ((desc)->id_max - (desc)->id_min + 1) + \
id \
)
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
struct descriptor
{
int device;
int port_min;
int port_max;
int index_min;
int index_max;
int id_min;
int id_max;
uint16_t *value;
int device;
int port_min;
int port_max;
int index_min;
int index_max;
int id_min;
int id_max;
uint16_t *value;
};
static struct descriptor joypad;
static struct descriptor *descriptors[] = {
&joypad
&joypad
};
static void fallback_log(enum retro_log_level level, const char *fmt, ...)
{
(void)level;
va_list va;
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
(void)level;
va_list va;
va_start(va, fmt);
vfprintf(stderr, fmt, va);
va_end(va);
}
void retro_init(void)
{
int size;
unsigned i;
struct descriptor *desc = NULL;
const char *dir = NULL;
int size;
unsigned i;
struct descriptor *desc = NULL;
const char * dir = NULL;
joypad.device = RETRO_DEVICE_JOYPAD;
joypad.port_min = 0;
joypad.port_max = 7;
joypad.index_min = 0;
joypad.index_max = 0;
joypad.id_min = RETRO_DEVICE_ID_JOYPAD_B;
joypad.id_max = RETRO_DEVICE_ID_JOYPAD_R3;
joypad.device = RETRO_DEVICE_JOYPAD;
joypad.port_min = 0;
joypad.port_max = 7;
joypad.index_min = 0;
joypad.index_max = 0;
joypad.id_min = RETRO_DEVICE_ID_JOYPAD_B;
joypad.id_max = RETRO_DEVICE_ID_JOYPAD_R3;
num_samples_per_frame = SAMPLE_RATE / FPS_RATE;
num_samples_per_frame = SAMPLE_RATE / FPS_RATE;
frame_sample_buf = (int16_t*)memalign_alloc(128, num_samples_per_frame * 2 * sizeof(int16_t));
frame_sample_buf = (int16_t *)memalign_alloc(128, num_samples_per_frame * 2 * sizeof(int16_t));
memset(frame_sample_buf, 0, num_samples_per_frame * 2 * sizeof(int16_t));
memset(frame_sample_buf, 0, num_samples_per_frame * 2 * sizeof(int16_t));
log_cb(RETRO_LOG_DEBUG, "retro_init");
log_cb(RETRO_LOG_DEBUG, "retro_init");
sprintf(retro_base_directory,"/tmp");
sprintf(retro_base_directory, "/tmp");
if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
{
if (strlen(dir))
snprintf(retro_base_directory, sizeof(retro_base_directory), "%s", dir);
}
if (environ_cb(RETRO_ENVIRONMENT_GET_SYSTEM_DIRECTORY, &dir) && dir)
{
if (strlen(dir))
{
snprintf(retro_base_directory, sizeof(retro_base_directory), "%s", dir);
}
}
if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir)
{
// If save directory is defined use it, otherwise use system directory
if (strlen(dir))
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", dir);
else
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", retro_base_directory);
}
if (environ_cb(RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY, &dir) && dir)
{
// If save directory is defined use it, otherwise use system directory
if (strlen(dir))
{
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", dir);
}
else
{
snprintf(retro_save_directory, sizeof(retro_save_directory), "%s", retro_base_directory);
}
}
frame_buf = (uint32_t *) calloc(WIDTH * HEIGHT, sizeof(uint32_t));
frame_buf = (uint32_t *)calloc(WIDTH * HEIGHT, sizeof(uint32_t));
mrboom_init();
mrboom_init();
/* joypads Allocate descriptor values */
for (i = 0; i < ARRAY_SIZE(descriptors); i++) {
desc = descriptors[i];
size = DESC_NUM_PORTS(desc) * DESC_NUM_INDICES(desc) * DESC_NUM_IDS(desc);
descriptors[i]->value = (uint16_t*)calloc(size, sizeof(uint16_t));
}
/* joypads Allocate descriptor values */
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
{
desc = descriptors[i];
size = DESC_NUM_PORTS(desc) * DESC_NUM_INDICES(desc) * DESC_NUM_IDS(desc);
descriptors[i]->value = (uint16_t *)calloc(size, sizeof(uint16_t));
}
}
void retro_deinit(void)
{
unsigned i;
unsigned i;
free(frame_buf);
memalign_free(frame_sample_buf);
frame_buf = NULL;
free(frame_buf);
memalign_free(frame_sample_buf);
frame_buf = NULL;
/* Free descriptor values */
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
{
free(descriptors[i]->value);
descriptors[i]->value = NULL;
}
/* Free descriptor values */
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
{
free(descriptors[i]->value);
descriptors[i]->value = NULL;
}
mrboom_deinit();
mrboom_deinit();
}
unsigned retro_api_version(void)
{
return RETRO_API_VERSION;
return(RETRO_API_VERSION);
}
void retro_set_controller_port_device(unsigned port, unsigned device)
{
log_cb(RETRO_LOG_INFO, "%s: Plugging device %u into port %u.\n", GAME_NAME, device, port);
log_cb(RETRO_LOG_INFO, "%s: Plugging device %u into port %u.\n", GAME_NAME, device, port);
}
void retro_get_system_info(struct retro_system_info *info)
{
memset(info, 0, sizeof(*info));
info->library_name = GAME_NAME;
memset(info, 0, sizeof(*info));
info->library_name = GAME_NAME;
#ifdef GIT_VERSION
info->library_version = GAME_VERSION GIT_VERSION;
info->library_version = GAME_VERSION GIT_VERSION;
#else
info->library_version = GAME_VERSION;
info->library_version = GAME_VERSION;
#endif
info->need_fullpath = false;
info->valid_extensions = NULL;
info->need_fullpath = false;
info->valid_extensions = NULL;
}
void retro_get_system_av_info(struct retro_system_av_info *info)
{
float aspect = 16.0f / 9.0f;
float aspect = 16.0f / 9.0f;
float sampling_rate = SAMPLE_RATE;
float sampling_rate = SAMPLE_RATE;
info->timing.fps = FPS_RATE;
info->timing.sample_rate = sampling_rate;
info->geometry.base_width = WIDTH;
info->geometry.base_height = HEIGHT;
info->geometry.max_width = WIDTH;
info->geometry.max_height = HEIGHT;
info->geometry.aspect_ratio = aspect;
info->timing.fps = FPS_RATE;
info->timing.sample_rate = sampling_rate;
info->geometry.base_width = WIDTH;
info->geometry.base_height = HEIGHT;
info->geometry.max_width = WIDTH;
info->geometry.max_height = HEIGHT;
info->geometry.aspect_ratio = aspect;
}
void retro_set_environment(retro_environment_t cb)
{
environ_cb = cb;
bool no_content = true;
cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &no_content);
if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging))
log_cb = logging.log;
else
log_cb = fallback_log;
std::vector<const retro_variable*> vars_systems;
// Add the Global core options
vars_systems.push_back(&var_mrboom_teammode);
vars_systems.push_back(&var_mrboom_nomonster);
vars_systems.push_back(&var_mrboom_autofire);
environ_cb = cb;
bool no_content = true;
cb(RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME, &no_content);
if (cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &logging))
{
log_cb = logging.log;
}
else
{
log_cb = fallback_log;
}
std::vector <const retro_variable *> vars_systems;
// Add the Global core options
vars_systems.push_back(&var_mrboom_teammode);
vars_systems.push_back(&var_mrboom_nomonster);
vars_systems.push_back(&var_mrboom_autofire);
#define NB_VARS_SYSTEMS 3
assert(vars_systems.size()==NB_VARS_SYSTEMS);
// Add the System core options
int idx_var = 0;
struct retro_variable vars[NB_VARS_SYSTEMS + 1]; // + 1 for the empty ending retro_variable
for (int i = 0; i < NB_VARS_SYSTEMS; i++, idx_var++)
{
vars[idx_var] = *vars_systems[i];
log_cb(RETRO_LOG_INFO, "retro_variable (SYSTEM) { '%s', '%s' }\n", vars[idx_var].key, vars[idx_var].value);
}
vars[idx_var] = var_empty;
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void*)vars);
#define NB_VARS_SYSTEMS 3
assert(vars_systems.size() == NB_VARS_SYSTEMS);
// Add the System core options
int idx_var = 0;
struct retro_variable vars[NB_VARS_SYSTEMS + 1]; // + 1 for the empty ending retro_variable
for (int i = 0; i < NB_VARS_SYSTEMS; i++, idx_var++)
{
vars[idx_var] = *vars_systems[i];
log_cb(RETRO_LOG_INFO, "retro_variable (SYSTEM) { '%s', '%s' }\n", vars[idx_var].key, vars[idx_var].value);
}
vars[idx_var] = var_empty;
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars);
}
void retro_set_audio_sample(retro_audio_sample_t cb)
{
audio_cb = cb;
audio_cb = cb;
}
void retro_set_audio_sample_batch(retro_audio_sample_batch_t cb)
{
audio_batch_cb = cb;
audio_batch_cb = cb;
}
void retro_set_input_poll(retro_input_poll_t cb)
{
input_poll_cb = cb;
input_poll_cb = cb;
}
void retro_set_input_state(retro_input_state_t cb)
{
input_state_cb = cb;
input_state_cb = cb;
}
void retro_set_video_refresh(retro_video_refresh_t cb)
{
video_cb = cb;
video_cb = cb;
}
void retro_reset(void)
@ -238,165 +246,192 @@ void retro_reset(void)
static void update_input(void)
{
uint16_t state;
int offset;
int port;
int index;
int id;
unsigned i;
uint16_t state;
int offset;
int port;
int index;
int id;
unsigned i;
/* Poll input */
input_poll_cb();
/* Poll input */
input_poll_cb();
/* Parse descriptors */
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
{
/* Get current descriptor */
struct descriptor *desc = descriptors[i];
/* Parse descriptors */
for (i = 0; i < ARRAY_SIZE(descriptors); i++)
{
/* Get current descriptor */
struct descriptor *desc = descriptors[i];
/* Go through range of ports/indices/IDs */
for (port = desc->port_min; port <= desc->port_max; port++)
for (index = desc->index_min; index <= desc->index_max; index++)
for (id = desc->id_min; id <= desc->id_max; id++)
{
/* Compute offset into array */
offset = DESC_OFFSET(desc, port, index, id);
/* Go through range of ports/indices/IDs */
for (port = desc->port_min; port <= desc->port_max; port++)
{
for (index = desc->index_min; index <= desc->index_max; index++)
{
for (id = desc->id_min; id <= desc->id_max; id++)
{
/* Compute offset into array */
offset = DESC_OFFSET(desc, port, index, id);
/* Get new state */
state = input_state_cb(port,
desc->device,
index,
id);
/* Update state */
if (desc->value[offset] != state) {
mrboom_update_input(id,port,state,false);
}
desc->value[offset] = state;
}
}
/* Get new state */
state = input_state_cb(port,
desc->device,
index,
id);
/* Update state */
if (desc->value[offset] != state)
{
mrboom_update_input(id, port, state, false);
}
desc->value[offset] = state;
}
}
}
}
}
void update_vga(uint32_t *buf, unsigned stride)
{
static uint32_t matrixPalette[NB_COLORS_PALETTE];
unsigned x, y;
int z = 0;
uint32_t *line = buf;
static uint32_t matrixPalette[NB_COLORS_PALETTE];
unsigned x, y;
int z = 0;
uint32_t * line = buf;
do {
matrixPalette[z/3]= ((m.vgaPalette[z]*4) << 16) | ((m.vgaPalette[z+1]*4) << 8) | (m.vgaPalette[z+2]*4);
z+=3;
} while (z!=NB_COLORS_PALETTE*3);
do
{
matrixPalette[z / 3] = ((m.vgaPalette[z] * 4) << 16) | ((m.vgaPalette[z + 1] * 4) << 8) | (m.vgaPalette[z + 2] * 4);
z += 3;
} while (z != NB_COLORS_PALETTE * 3);
for (y = 0; y < HEIGHT; y++, line += stride)
{
for (x = 0; x < WIDTH; x++)
{
if (y<HEIGHT)
line[x] = matrixPalette[m.vgaRam[x+y*WIDTH]];
}
}
for (y = 0; y < HEIGHT; y++, line += stride)
{
for (x = 0; x < WIDTH; x++)
{
if (y < HEIGHT)
{
line[x] = matrixPalette[m.vgaRam[x + y * WIDTH]];
}
}
}
}
static void render_checkered(void)
{
mrboom_sound();
mrboom_sound();
/* Try rendering straight into VRAM if we can. */
uint32_t *buf = NULL;
unsigned stride = 0;
struct retro_framebuffer fb = {0};
fb.width = WIDTH;
fb.height = HEIGHT;
fb.access_flags = RETRO_MEMORY_ACCESS_WRITE;
if (environ_cb(RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER, &fb) && fb.format == RETRO_PIXEL_FORMAT_XRGB8888)
{
buf = (uint32_t *) fb.data;
stride = fb.pitch >> 2;
}
else
{
buf = frame_buf;
stride = WIDTH;
}
update_vga(buf,stride);
video_cb(buf, WIDTH, HEIGHT, stride << 2);
/* Try rendering straight into VRAM if we can. */
uint32_t *buf = NULL;
unsigned stride = 0;
struct retro_framebuffer fb = { 0 };
fb.width = WIDTH;
fb.height = HEIGHT;
fb.access_flags = RETRO_MEMORY_ACCESS_WRITE;
if (environ_cb(RETRO_ENVIRONMENT_GET_CURRENT_SOFTWARE_FRAMEBUFFER, &fb) && fb.format == RETRO_PIXEL_FORMAT_XRGB8888)
{
buf = (uint32_t *)fb.data;
stride = fb.pitch >> 2;
}
else
{
buf = frame_buf;
stride = WIDTH;
}
update_vga(buf, stride);
video_cb(buf, WIDTH, HEIGHT, stride << 2);
}
static void check_variables(void)
{
struct retro_variable var = {0};
var.key = var_mrboom_nomonster.key;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
{
if (strcmp(var.value, "ON") == 0)
setNoMonsterMode(false);
else
setNoMonsterMode(true);
}
var.key = var_mrboom_autofire.key;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
{
if (strcmp(var.value, "ON") == 0)
setAutofire(true);
else
setAutofire(false);
}
var.key = var_mrboom_teammode.key;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
{
if (strcmp(var.value, "Selfie") == 0)
setTeamMode(0);
else if (strcmp(var.value, "Sex") == 0)
setTeamMode(2);
else
setTeamMode(1);
}
struct retro_variable var = { 0 };
var.key = var_mrboom_nomonster.key;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
{
if (strcmp(var.value, "ON") == 0)
{
setNoMonsterMode(false);
}
else
{
setNoMonsterMode(true);
}
}
var.key = var_mrboom_autofire.key;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
{
if (strcmp(var.value, "ON") == 0)
{
setAutofire(true);
}
else
{
setAutofire(false);
}
}
var.key = var_mrboom_teammode.key;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var))
{
if (strcmp(var.value, "Selfie") == 0)
{
setTeamMode(0);
}
else if (strcmp(var.value, "Sex") == 0)
{
setTeamMode(2);
}
else
{
setTeamMode(1);
}
}
}
void retro_run(void)
{
static int frame=0;
int newFrameNumber=frameNumber();
frame++;
if (frame!=newFrameNumber) {
if ((frame) && (newFrameNumber)) {
log_error("Network resynched: %d -> %d\n",frame,newFrameNumber);
}
}
frame=newFrameNumber;
update_input();
mrboom_deal_with_autofire();
render_checkered();
audio_callback();
program();
mrboom_reset_special_keys();
mrboom_tick_ai();
if (m.executionFinished) {
log_cb(RETRO_LOG_INFO, "Exit.\n");
environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL);
}
bool updated = false;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
check_variables();
}
static int frame = 0;
int newFrameNumber = frameNumber();
frame++;
if (frame != newFrameNumber)
{
if ((frame) && (newFrameNumber))
{
log_error("Network resynched: %d -> %d\n", frame, newFrameNumber);
}
}
frame = newFrameNumber;
update_input();
mrboom_deal_with_autofire();
render_checkered();
audio_callback();
program();
mrboom_reset_special_keys();
mrboom_tick_ai();
if (m.executionFinished)
{
log_cb(RETRO_LOG_INFO, "Exit.\n");
environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, NULL);
}
bool updated = false;
if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated)
{
check_variables();
}
}
bool retro_load_game(const struct retro_game_info *info)
{
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
{
log_cb(RETRO_LOG_INFO, "XRGB8888 is not supported.\n");
return false;
}
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
check_variables();
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
{
log_cb(RETRO_LOG_INFO, "XRGB8888 is not supported.\n");
return(false);
}
(void)info;
return true;
check_variables();
(void)info;
return(true);
}
void retro_unload_game(void)
@ -405,77 +440,88 @@ void retro_unload_game(void)
unsigned retro_get_region(void)
{
return RETRO_REGION_NTSC;
return(RETRO_REGION_NTSC);
}
bool retro_load_game_special(unsigned type, const struct retro_game_info *info, size_t num)
{
return retro_load_game(NULL);
return(retro_load_game(NULL));
}
#define HARDCODED_RETRO_SERIALIZE_SIZE SIZE_SER+13*8
#define HARDCODED_RETRO_SERIALIZE_SIZE SIZE_SER + 13 * 8
size_t retro_serialize_size(void)
{
size_t result=HARDCODED_RETRO_SERIALIZE_SIZE;
assert(tree[0]!=NULL);
if (tree[0]!=NULL) {
result=(SIZE_SER+tree[0]->serialize_size()*nb_dyna);
assert(HARDCODED_RETRO_SERIALIZE_SIZE==result);
} else {
log_error("retro_serialize_size returning hardcoded value.\n");
}
assert(SIZE_MEM_MAX>result);
return result;
size_t result = HARDCODED_RETRO_SERIALIZE_SIZE;
assert(tree[0] != NULL);
if (tree[0] != NULL)
{
result = (SIZE_SER + tree[0]->serialize_size() * nb_dyna);
assert(HARDCODED_RETRO_SERIALIZE_SIZE == result);
}
else
{
log_error("retro_serialize_size returning hardcoded value.\n");
}
assert(SIZE_MEM_MAX > result);
return(result);
}
bool retro_serialize(void *data_, size_t size)
{
memcpy(data_, &m.FIRST_RW_VARIABLE, SIZE_SER);
if (is_little_endian()==false) {
fixBigEndian(data_);
}
size_t offset=SIZE_SER;
for (int i=0; i<nb_dyna; i++) {
assert(tree[i]!=NULL);
tree[i]->serialize(((char *) data_)+offset);
offset+=tree[i]->serialize_size();
}
return true;
memcpy(data_, &m.FIRST_RW_VARIABLE, SIZE_SER);
if (is_little_endian() == false)
{
fixBigEndian(data_);
}
size_t offset = SIZE_SER;
for (int i = 0; i < nb_dyna; i++)
{
assert(tree[i] != NULL);
tree[i]->serialize(((char *)data_) + offset);
offset += tree[i]->serialize_size();
}
return(true);
}
bool retro_unserialize(const void *data_, size_t size)
{
if (size!=retro_serialize_size()) {
log_error("retro_unserialize error %d/%d\n",size,retro_serialize_size());
return false;
}
if (is_little_endian()==false) {
char dataTmp[SIZE_MEM_MAX];
memcpy(dataTmp,data_, SIZE_SER);
fixBigEndian(dataTmp);
memcpy(&m.FIRST_RW_VARIABLE, dataTmp, SIZE_SER);
} else {
memcpy(&m.FIRST_RW_VARIABLE, data_, SIZE_SER);
}
size_t offset=SIZE_SER;
for (int i=0; i<nb_dyna; i++) {
assert(tree[i]!=NULL);
tree[i]->unserialize(((char *) data_)+offset);
offset+=tree[i]->serialize_size();
}
return true;
if (size != retro_serialize_size())
{
log_error("retro_unserialize error %d/%d\n", size, retro_serialize_size());
return(false);
}
if (is_little_endian() == false)
{
char dataTmp[SIZE_MEM_MAX];
memcpy(dataTmp, data_, SIZE_SER);
fixBigEndian(dataTmp);
memcpy(&m.FIRST_RW_VARIABLE, dataTmp, SIZE_SER);
}
else
{
memcpy(&m.FIRST_RW_VARIABLE, data_, SIZE_SER);
}
size_t offset = SIZE_SER;
for (int i = 0; i < nb_dyna; i++)
{
assert(tree[i] != NULL);
tree[i]->unserialize(((char *)data_) + offset);
offset += tree[i]->serialize_size();
}
return(true);
}
void *retro_get_memory_data(unsigned id)
{
(void)id;
return NULL;
(void)id;
return(NULL);
}
size_t retro_get_memory_size(unsigned id)
{
(void)id;
return 0;
(void)id;
return(0);
}
void retro_cheat_reset(void)
@ -484,14 +530,16 @@ void retro_cheat_reset(void)
void retro_cheat_set(unsigned index, bool enabled, const char *code)
{
(void)index;
(void)enabled;
(void)code;
(void)index;
(void)enabled;
(void)code;
}
void show_message(const char * message) {
struct retro_message msg;
msg.msg = message;
msg.frames = 80;
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void*)&msg);
void show_message(const char *message)
{
struct retro_message msg;
msg.msg = message;
msg.frames = 80;
environ_cb(RETRO_ENVIRONMENT_SET_MESSAGE, (void *)&msg);
}

View File

@ -3,12 +3,13 @@
#ifdef __cplusplus
extern "C" {
#endif
#define SIZE_MEM_MAX 30000
#define SIZE_MEM_MAX 30000
void update_vga(uint32_t *buf, unsigned stride);
void show_message(const char * show_message);
void show_message(const char *show_message);
size_t retro_serialize_size(void);
bool retro_serialize(void *data_, size_t size);
bool retro_unserialize(const void *data_, size_t size);
#ifdef __cplusplus
}
#endif

137239
retro_data.h

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff