// // This computes obj_C = obj_Z - obj_A from obj_K // unsigned long lengthAfterObjectKey( Ref * obj_K ) { // Keys fall into the following categories: FunctionKey, SimpleKey, Pointer to Keys Ref key = *obj_K; if ( IsSimpleKey( key ) ) { switch ( LayoutOfSimpleKey( key ) ) { //switch ( KindOfSimpleKey( key ) ) { case RECORD_LAYOUT: { //case MAP_KIND: //case PAIR_KIND: //case RECORD_KIND: { assert( LayoutOfSimpleKey( key ) == RECORD_LAYOUT ); assert( KindOfSimpleKey( key ) == PAIR_KIND || KindOfSimpleKey( key ) == MAP_KIND || KindOfSimpleKey( key ) == RECORD_KIND ); return sizeAfterKeyOfRecordLayout( obj_K ); break; } case VECTOR_LAYOUT: { //case VECTOR_KIND: { assert( LayoutOfSimpleKey( key ) == VECTOR_LAYOUT ); assert( KindOfSimpleKey( key ) == VECTOR_KIND ); return sizeAfterKeyOfVectorLayout( obj_K ); break; } case MIXED_LAYOUT: { assert( LayoutOfSimpleKey( key ) == MIXED_LAYOUT ); return sizeAfterKeyOfMixedLayout( obj_K ); break; } case STRING_LAYOUT: { //case STRING_KIND: { assert( LayoutOfSimpleKey( key ) == STRING_LAYOUT ); assert( KindOfSimpleKey( key ) == STRING_KIND ); return sizeAfterKeyOfStringLayout( obj_K ); break; } case WRECORD_LAYOUT: { assert( LayoutOfSimpleKey( key ) == WRECORD_LAYOUT ); return sizeAfterKeyOfWRecordLayout( obj_K ); break; } default: throw UnreachableError(); } } else if ( IsFunctionKey( key ) ) { return sizeAfterKeyOfFn( obj_K ); } else if ( IsObj( key ) ) { return sizeAfterKeyOfInstance( obj_K ); } else { throw Ginger::Mishap( "Cannot take length of this" ); } }
// // This computes obj_K from obj_A. // Ref * findObjectKey( Ref * obj_A ) { // Cases are that 'obj_A' is pointing at // 1. FnLengthKey. // 2. NonKey* Key series if ( IsFnLength( *obj_A ) ) { // We are at the start of a function. // It has a fixed offset to the key. return obj_A + OFFSET_FROM_FN_LENGTH_TO_KEY; } else { for ( int n = 0; n < MAX_OFFSET_FROM_START_TO_KEY; n++ ) { // // Note that this function is called on objects that have been // forwarded but not yet scanned by the GC. So the test for the // key has to be capable of coping with a forwarded key. This // test is stupider and restricts values in front of the key to // simple values. // // A smarter test is // 1. Are you a simple key? Job done. A: yes // 2. Are you an object? Define K = *you // 2a. Is *K the keykey? If so job done. A: yes // 2b. Is *K forwarded? Define F = *K // 2c. Is *F the keykey? If so A: yes // 3. Otherwise done A: no // /* I think the code would look like this. if ( IsSimpleKey( *obj_A ) ) return obj_A; if ( IsObj( *obj_A ) ) { if ( *RefToPtr4( *obj_A ) == sysClassKey ) return obj_A; } if ( IsFwd( *obj_A ) ) { Ref K = *FwdToPtr4( *obj_A ); if ( IsObj( K ) ) { if ( *RefToPtr4( K ) == sysClassKey ) return obj_A; } } */ Ref * x = obj_A + n; Ref k = *x; if ( IsSimpleKey( k ) || IsObj( k ) || IsFwd( k ) ) { return x; } } throw UnreachableError(); } }
bool Chessman::checkPos(const Point &_pos)const { INFO("info Chessman::checkPos executed.\n"); int x = _pos.getX(); int y = _pos.getY(); if (x < 1 || y < 1 || x >= BOARD_X || y >= BOARD_Y){ return false; } switch (type){ case R_JIANG: if (abs(9-x)<=1 && abs(5-y)<=1){ return true; }else{ return false; } break; case B_JIANG: if (abs(2-x)<=1 && abs(5-y)<=1){ return true; }else{ return false; } break; case R_SHI: if (x==8 || x==10){ if (y==4 || y==6){ return true; }else{ return false; } }else if (x==9 && y==5){ return true; }else{ return false; } break; case B_SHI: if (x==1 || x==3){ if (y==4 || y==6){ return true; }else{ return false; } }else if (x==2 && y==5){ return true; }else{ return false; } break; case R_XIANG: if (x==6 || x==10){ if (y==3 || y==7){ return true; }else{ return false; } }else if (x==8){ if (y==1 || y==5 || y==9){ return true; }else{ return false; } }else{ return false; } break; case B_XIANG: if (x==1 || x==5){ if (y==3 || y==7){ return true; }else{ return false; } }else if (x==3){ if (y==1 || y==5 || y==9){ return true; }else{ return false; } }else{ return false; } break; case R_BING: if (x > 5){ if ((x<8)&&(y%2==1)){//y==1,3,5,7,9 return true; }else{ return false; } } return true; break; case B_BING: if (x < 6){ if ((x>3)&&(y%2==1)){//y==1,3,5,7,9 return true; }else{ return false; } } return true; break; case BOARD: case NON: printf("312"); throw InvalidMoveError(); break; default: return true; }; throw UnreachableError(); }
bool Chessman::canGo(Chessman *maps[11][10], const Point &_pos)const { printf("info Chessman::canGo entered\n"); if (!checkPos(_pos)){ return false; } if (pos == _pos){//precheck for speed return false; } int x = pos.getX(); int y = pos.getY(); int _x = _pos.getX(); int _y = _pos.getY(); switch (type){ case R_JIANG: case B_JIANG: if (abs(x-_x)+abs(y-_y)==1){ return true; } return false; break; case R_SHI: case B_SHI: if (abs(x-_x)==1 && abs(y-_y)==1){ return true; } return false; break; case R_XIANG: case B_XIANG: if (abs(x-_x)==2 && abs(y-_y)==2){ if (maps[(x+_x)/2][(y+_y)/2]->getType() == NON){ return true; } } return false; break; case R_MA: case B_MA: if (abs(x-_x)==2){ if (abs(y-_y)==1 && maps[(x+_x)/2][y]->getType()==NON){ return true; } }else if (abs(x-_x)==1){ if (abs(y-_y)==2 && maps[x][(y+_y)/2]->getType()==NON){ return true; } } return false; break; case R_CHE: case B_CHE: if (x==_x){ int cnt = 0; int i = min(y, _y); int j = max(y, _y); while (++i<j){ if (maps[x][i]->getType() != NON){ ++cnt; } } if (cnt == 0){ return true; }else{ return false; } } if (y==_y){ int cnt = 0; int i = min(x, _x); int j = max(x, _x); while (++i<j){ if (maps[i][y]->getType() != NON){ ++cnt; } } if (cnt == 0){ return true; }else{ return false; } } return false; break; case R_PAO: case B_PAO: if (x==_x){ int cnt = 0; int i = min(y, _y); int j = max(y, _y); while (++i<j){ if (maps[x][i]->getType() != NON){ ++cnt; } } if ((maps[x][_y]->getType()==NON && cnt==0) || (maps[x][_y]->getType()!=NON && cnt==1)){ return true; }else{ return false; } } if (y==_y){ int cnt = 0; int i = min(x, _x); int j = max(x, _x); while (++i<j){ if (maps[i][y]->getType() != NON){ ++cnt; } } if ((maps[_x][y]->getType()==NON && cnt==0) || (maps[_x][y]->getType()!=NON && cnt==1)){ return true; }else{ return false; } } return false; break; case R_BING: if ((x==7 && _x==6 && y==_y) || (x==6 && _x==5 && y==_y)){ return true; } if (x<=5 && _x<=x && abs(x-_x)+abs(y-_y)==1){ return true; } return false; break; case B_BING: if ((x==4 && _x==5 && y==_y) || (x==5 && _x==6 && y==_y)){ return true; } if (x>=6 && _x>=x && abs(x-_x)+abs(y-_y)==1){ return true; } return false; break; default: printf("205"); throw InvalidMoveError(); }; throw UnreachableError(); }