Ejemplo n.º 1
0
//
//	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" );
	}
}
Ejemplo n.º 2
0
//
//	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();
	}
}
Ejemplo n.º 3
0
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();
}
Ejemplo n.º 4
0
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();
}