ExecStatus EqInt<VX,VY>::propagate(Space& home, const ModEventDelta&) { // Eliminate decided views from subscribed views int n_x = x.size(); for (int i=n_s; i--; ) switch (holds(x[i],y)) { case RT_FALSE: x[i].cancel(home,*this,PC_INT_DOM); x[i]=x[--n_s]; x[n_s]=x[--n_x]; break; case RT_TRUE: x[i].cancel(home,*this,PC_INT_DOM); x[i]=x[--n_s]; x[n_s]=x[--n_x]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n_x); if ((c < 0) || (c > n_x)) return ES_FAILED; // Eliminate decided views from unsubscribed views for (int i=n_x; i-- > n_s; ) switch (holds(x[i],y)) { case RT_FALSE: x[i]=x[--n_x]; break; case RT_TRUE: x[i]=x[--n_x]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n_x); if ((c < 0) || (c > n_x)) return ES_FAILED; if (c == 0) { // All views must be different GECODE_ES_CHECK(post_false(home,x,y)); return home.ES_SUBSUMED(*this); } if (c == n_x) { // All views must be equal GECODE_ES_CHECK(post_true(home,x,y)); return home.ES_SUBSUMED(*this); } int m = std::max(c,n_x-c)+1; assert(m <= n_x); // Now, there must be new subscriptions from x[n_s] up to x[m-1] while (n_s < m) x[n_s++].subscribe(home,*this,PC_INT_DOM,false); return ES_FIX; }
ExecStatus LqInt<VX,VY>::post(Home home, ViewArray<VX>& x, VY y, int c) { // Eliminate decided views int n_x = x.size(); for (int i=n_x; i--; ) switch (holds(x[i],y)) { case RT_FALSE: x[i] = x[--n_x]; break; case RT_TRUE: x[i] = x[--n_x]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n_x); if (c < 0) return ES_FAILED; if (c >= n_x) return ES_OK; // All views must be different if (c == 0) return post_false(home,x,y); (void) new (home) LqInt<VX,VY>(home,x,n_x-c+1,y,c); return ES_OK; }
ExecStatus EqInt<VX,VY>::post(Home home, ViewArray<VX>& x, VY y, int c) { // Eliminate decided views int n_x = x.size(); for (int i=n_x; i--; ) switch (holds(x[i],y)) { case RT_FALSE: x[i] = x[--n_x]; break; case RT_TRUE: x[i] = x[--n_x]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n_x); // RHS too small or too large if ((c < 0) || (c > n_x)) return ES_FAILED; // All views must be different if (c == 0) return post_false(home,x,y); // All views must be equal if (c == n_x) return post_true(home,x,y); // Compute how many subscriptions must be created int n_s = std::max(c,n_x-c)+1; assert(n_s <= n_x); (void) new (home) EqInt<VX,VY>(home,x,n_s,y,c); return ES_OK; }
ExecStatus GqInt<VX,VY>::post(Home home, ViewArray<VX>& x, VY y, int c) { // Eliminate decided views int n_x = x.size(); for (int i=n_x; i--; ) switch (holds(x[i],y)) { case RT_FALSE: x[i] = x[--n_x]; break; case RT_TRUE: x[i] = x[--n_x]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n_x); // RHS too large if (n_x < c) return ES_FAILED; // Whatever the x[i] take for values, the inequality is subsumed if (c <= 0) return ES_OK; // All views must be equal if (c == n_x) return post_true(home,x,y); (void) new (home) GqInt<VX,VY>(home,x,c+1,y,c); return ES_OK; }
SdbPacket *SdbPacketQueue:: get_packet() { mLock holds(this); SdbPacket *p = first; remove_pointer(p); return p; }
void do_move(GameInstance *g, const Server *s, Player *p, SR_Command *cmd) { int armies; SpeedRiskData *risk = (SpeedRiskData *)g->data; SR_Game_Status *status = &risk->status; if (!(holds(status, p, cmd->from) && holds(status, p, cmd->to))) { player_error(s, p, SR_ERR_NOT_OWNER); } else if (!borders(cmd->from, cmd->to)) { player_error(s, p, SR_ERR_INVALID_DESTINATION); } else if (cmd->armies>=status->countries[cmd->from].armies){ player_error(s, p, SR_ERR_NOT_ENOUGH_ARMIES); } else { armies = status->countries[cmd->to].armies + cmd->armies; if (armies > 255) cmd->armies = 255 - status->countries[cmd->to].armies; status->countries[cmd->from].armies -= cmd->armies; status->countries[cmd->to].armies += cmd->armies; tell_all_mv_at_result(g, s, SR_CMD_MOVE_RESULT, cmd->from, cmd->to); } }
void do_attack(GameInstance *g, const Server *s, Player *p, SR_Command *cmd) { SpeedRiskData *risk = (SpeedRiskData *)g->data; SR_Game_Status *status = &risk->status; int attacking, defending, attack_loss, defend_loss, defender; if (not_holds(status, p, cmd->from)) { player_error(s, p, SR_ERR_NOT_OWNER); } else if (holds(status, p, cmd->to)) { player_error(s, p, SR_ERR_INVALID_DESTINATION); } else if (!borders(cmd->from, cmd->to)) { player_error(s, p, SR_ERR_INVALID_DESTINATION); } else if (cmd->armies < 1 || cmd->armies >= status->countries[cmd->from].armies) { player_error(s, p, SR_ERR_NOT_ENOUGH_ARMIES); } else { attacking = cmd->armies > 3 ? 3 : cmd->armies; defending = status->countries[cmd->to].armies > 1 ? 2 : 1; roll_for_attack(attacking, defending, s->random, &attack_loss, &defend_loss); status->countries[cmd->from].armies -= attack_loss; status->countries[cmd->to].armies -= defend_loss; defender = status->countries[cmd->to].owner; if (status->countries[cmd->to].armies == 0) { attacking = cmd->armies - attack_loss; status->countries[cmd->from].armies -= attacking; status->countries[cmd->to].armies += attacking; status->countries[cmd->to].owner = p->in_game_id; risk->players[p->in_game_id].countries_held++; risk->players[defender].countries_held--; } tell_all_mv_at_result(g, s, SR_CMD_ATTACK_RESULT, cmd->from, cmd->to); if (risk->players[defender].countries_held == 0) { all_cmd_f(g, s, SR_CMD_DEFEAT, defender); if (risk->players[defender].player != NULL) { s->log(g, "%s defeated", risk->players[defender].player->name); } } if (risk->players[p->in_game_id].countries_held == risk->board->territories) { s->change_state(g, &SR_DONE); } } }
forceinline void ViewBase<VX,VY,VZ>::count(Space& home) { int n = x.size(); for (int i=n; i--; ) switch (holds(x[i],y)) { case RT_FALSE: x[i].cancel(home,*this,PC_INT_DOM); x[i]=x[--n]; break; case RT_TRUE: x[i].cancel(home,*this,PC_INT_DOM); x[i]=x[--n]; c--; break; case RT_MAYBE: break; default: GECODE_NEVER; } x.size(n); }
bool debug_holds() { return holds(); }
void SdbPacketQueue:: put_packet(SdbPacket *p) { mLock holds(this); append(p); }