00001 #include "osl/basic_type.h"
00002 #include "osl/bits/boardTable.h"
00003 #include "osl/bits/ptypeTable.h"
00004 #include "osl/simpleState.h"
00005 #include "osl/bits/squareCompressor.h"
00006
00007 #include <iostream>
00008
00009 bool osl::isValid(Player player)
00010 {
00011 return player==BLACK || player==WHITE;
00012 }
00013
00014 std::ostream& osl::operator<<(std::ostream& os,Player player)
00015 {
00016 if(player==BLACK)
00017 return os << "+";
00018 else
00019 return os << "-";
00020 }
00021
00022
00023
00024 bool osl::isValid(Ptype ptype)
00025 {
00026 return static_cast<int>(ptype)>=PTYPE_MIN
00027 && static_cast<int>(ptype)<=PTYPE_MAX;
00028 }
00029
00030 bool osl::isValidPtypeO(int ptypeO)
00031 {
00032 return (ptypeO >= PTYPEO_MIN) && (ptypeO <= PTYPEO_MAX);
00033 }
00034
00035 std::istream& osl::operator>>(std::istream& is, osl::Ptype& ptype)
00036 {
00037 std::string s;
00038 is >> s;
00039 if (s == "PTYPE_EMPTY")
00040 ptype = PTYPE_EMPTY;
00041 else if (s == "PTYPE_EDGE")
00042 ptype = PTYPE_EDGE;
00043 else if (s == "PPAWN")
00044 ptype = PPAWN;
00045 else if (s == "PLANCE")
00046 ptype = PLANCE;
00047 else if (s == "PKNIGHT")
00048 ptype = PKNIGHT;
00049 else if (s == "PSILVER")
00050 ptype = PSILVER;
00051 else if (s == "PBISHOP")
00052 ptype = PBISHOP;
00053 else if (s == "PROOK")
00054 ptype = PROOK;
00055 else if (s == "KING")
00056 ptype = KING;
00057 else if (s == "GOLD")
00058 ptype = GOLD;
00059 else if (s == "PAWN")
00060 ptype = PAWN;
00061 else if (s == "LANCE")
00062 ptype = LANCE;
00063 else if (s == "KNIGHT")
00064 ptype = KNIGHT;
00065 else if (s == "SILVER")
00066 ptype = SILVER;
00067 else if (s == "BISHOP")
00068 ptype = BISHOP;
00069 else if (s == "ROOK")
00070 ptype = ROOK;
00071 else{
00072 std::cerr << "Incorrect input : " << s << std::endl;
00073 ptype = PTYPE_EMPTY;
00074 }
00075 return is;
00076 }
00077
00078 std::ostream& osl::operator<<(std::ostream& os,const osl::Ptype ptype)
00079 {
00080 return os << Ptype_Table.getName(ptype);
00081 }
00082
00083 std::ostream& osl::operator<<(std::ostream& os,const osl::PtypeO ptypeO)
00084 {
00085 if (isPiece(ptypeO))
00086 return os << "PtypeO(" << getOwner(ptypeO) << ","
00087 << getPtype(ptypeO) << ")";
00088 return os << "PtypeO(" << (int)ptypeO << "," << getPtype(ptypeO) << ")";
00089 }
00090
00091
00092
00093 bool osl::isValid(Direction d){
00094 return DIRECTION_MIN<=d && d<=DIRECTION_MAX;
00095 }
00096
00097 std::ostream& osl::operator<<(std::ostream& os,const Direction d){
00098 static const char* names[]={
00099 "UL","U","UR","L",
00100 "R","DL","D","DR",
00101 "UUL","UUR","LONG_UL",
00102 "LONG_U","LONG_UR","LONG_L",
00103 "LONG_R","LONG_DL","LONG_D","LONG_DR"
00104 };
00105 return os << names[static_cast<int>(d)];
00106 }
00107
00108 #define OFFSET_INDEX(dx,dy) ((dx*BOARD_HEIGHT + dy) - OFFSET_MIN)
00109
00110 osl::Offset::Offset(Player player, Direction direction)
00111 {
00112 *this = Board_Table.getOffset(player, direction);
00113 }
00114
00119 int osl::Offset::dx() const
00120 {
00121 switch (index())
00122 {
00123 case OFFSET_INDEX(-1,-2): return -1;
00124 case OFFSET_INDEX(1,-2): return 1;
00125 case OFFSET_INDEX(-1,-1): return -1;
00126 case OFFSET_INDEX(0,-1): return 0;
00127 case OFFSET_INDEX(1,-1): return 1;
00128 case OFFSET_INDEX(-1,0): return -1;
00129 case OFFSET_INDEX(1,0): return 1;
00130 case OFFSET_INDEX(-1,1): return -1;
00131 case OFFSET_INDEX(0,1): return 0;
00132 case OFFSET_INDEX(1,1): return 1;
00133 case OFFSET_INDEX(-1,2): return -1;
00134 case OFFSET_INDEX(1,2): return 1;
00135 default:
00136 std::cerr << index() << " " << ZERO().index() << "\n";
00137 assert(0);
00138 }
00139 return 0;
00140 }
00141
00146 int osl::Offset::dy() const
00147 {
00148 switch (index())
00149 {
00150 case OFFSET_INDEX(-1,-2): return -2;
00151 case OFFSET_INDEX(1,-2): return -2;
00152 case OFFSET_INDEX(-1,-1): return -1;
00153 case OFFSET_INDEX(0,-1): return -1;
00154 case OFFSET_INDEX(1,-1): return -1;
00155 case OFFSET_INDEX(-1,0): return 0;
00156 case OFFSET_INDEX(1,0): return 0;
00157 case OFFSET_INDEX(-1,1): return 1;
00158 case OFFSET_INDEX(0,1): return 1;
00159 case OFFSET_INDEX(1,1): return 1;
00160 case OFFSET_INDEX(-1,2): return 2;
00161 case OFFSET_INDEX(1,2): return 2;
00162 default: assert(0);
00163 }
00164 return 0;
00165 }
00166
00167 #ifndef MINIMAL
00168 std::ostream& osl::operator<<(std::ostream& os, Offset offset)
00169 {
00170 return os << "offset(" << offset.intValue() << ')';
00171 }
00172 #endif
00173
00174
00175
00176 static_assert(sizeof(osl::Square) == 4, "square size");
00177
00178 bool osl::Square::isOnBoardSlow() const
00179 {
00180 return (1<=x() && x() <=9
00181 && 1<=y() && y() <=9);
00182 }
00183
00184 bool osl::Square::isValid() const
00185 {
00186 return isPieceStand() || isOnBoard();
00187 }
00188
00189
00190 const osl::Square osl::
00191 Square::neighbor(Player P, Direction D) const
00192 {
00193 return Board_Table.nextSquare(P, *this, D);
00194 }
00195
00196 const osl::Square osl::
00197 Square::back(Player P, Direction D) const
00198 {
00199 return Board_Table.nextSquare(alt(P), *this, D);
00200 }
00201
00202 bool osl::Square::isNeighboring8(Square to) const {
00203 return (*this != to)
00204 && (to == *this+Board_Table.getShortOffsetNotKnight(Offset32(to,*this)));
00205 }
00206
00207 std::ostream& osl::operator<<(std::ostream& os, Square square)
00208 {
00209 if (square.isPieceStand())
00210 return os << "OFF";
00211 return os << "Square(" << square.x() << square.y() << ")";
00212 }
00213
00214 static_assert(sizeof(osl::Piece) == 4, "piece size");
00215
00216 std::ostream& osl::operator<<(std::ostream& os,const Piece piece)
00217 {
00218 if (piece.isPiece())
00219 os << "Piece(" << piece.owner() << "," << piece.ptype()
00220 << ",num=" << piece.number()
00221 << "," << piece.square() << ')';
00222 else if (piece == Piece::EMPTY())
00223 os << "PIECE_EMPTY";
00224 else if (piece == Piece::EDGE())
00225 os << "PIECE_EDGE";
00226 else
00227 os << "unkown piece?!";
00228 return os;
00229 }
00230
00231 const osl::Piece osl::Piece::makeKing(Player owner, Square position)
00232 {
00233 const int number = ((owner == BLACK)
00234 ? (int)KingTraits<BLACK>::index
00235 : (int)KingTraits<WHITE>::index);
00236 return Piece(owner, KING, number, position);
00237 }
00238
00239
00240
00241 namespace osl
00242 {
00243 static_assert(sizeof(Move) == 4, "move size");
00244 }
00245
00246 bool osl::Move::isValid() const
00247 {
00248 if (! isNormal())
00249 return false;
00250 const Square from = this->from();
00251 if (! from.isValid())
00252 return false;
00253 const Square to = this->to();
00254 if (! to.isOnBoard())
00255 return false;
00256 return osl::isValid(ptype())
00257 && osl::isValid(capturePtype())
00258 && capturePtype()!=KING
00259 && osl::isValid(player());
00260 }
00261
00262 const osl::Move osl::Move::rotate180() const
00263 {
00264 if (isPass())
00265 return Move::PASS(alt(player()));
00266 if (! isNormal())
00267 return *this;
00268 return Move(from().rotate180Safe(), to().rotate180(), ptype(),
00269 capturePtype(), isPromotion(), alt(player()));
00270 }
00271
00272 std::ostream& osl::operator<<(std::ostream& os,const Move move)
00273 {
00274 if (move == Move::DeclareWin())
00275 return os << "MOVE_DECLARE_WIN";
00276 if (move.isInvalid())
00277 return os << "MOVE_INVALID";
00278 if (move.isPass())
00279 return os << "MOVE_PASS";
00280 const Player turn = move.player();
00281 if (move.isValid())
00282 {
00283 if (move.from().isPieceStand())
00284 {
00285 os << "Drop(" << turn << "," << move.ptype() << "," << move.to() << ")";
00286 }
00287 else
00288 {
00289 const Ptype capture_ptype=move.capturePtype();
00290 os << "Move(" << turn << "," << move.ptype() << ","
00291 << move.from() << "->" << move.to() ;
00292 if (move.promoteMask())
00293 os << ",promote";
00294 if (capture_ptype != PTYPE_EMPTY)
00295 os << ",capture=" << capture_ptype;
00296 os << ")";
00297 }
00298 }
00299 else
00300 {
00301 os << "InvalidMove " << move.from() << " " << move.to()
00302 << " " << move.ptypeO() << " " << move.oldPtypeO()
00303 << " " << move.promoteMask()
00304 << " " << move.capturePtype() << "\n";
00305 }
00306 return os;
00307 }
00308
00309 unsigned int osl::Move::hash() const
00310 {
00311 assert(capturePtype() == PTYPE_EMPTY);
00312
00313 return intValue();
00314 }
00315
00316 const osl::Move osl::Move::
00317 fromMove16(Move16 move16, const SimpleState& state)
00318 {
00319 if (move16==MOVE16_NONE)
00320 return Move();
00321 Player turn=state.turn();
00322 Square to=SquareCompressor::melt((move16>>8)&0x7f);
00323 if((move16&0x80)!=0){
00324 Ptype ptype=(Ptype)(move16-0x80);
00325 return Move(to,ptype,turn);
00326 }
00327 Square from=SquareCompressor::melt(move16&0x7f);
00328 Ptype ptype=state[from].ptype();
00329 Ptype capture_ptype=state[to].ptype();
00330 bool is_promote=(move16&0x8000)!=0;
00331 if(is_promote)
00332 return Move(from,to,::osl::promote(ptype),capture_ptype,true,turn);
00333 else
00334 return Move(from,to,ptype,capture_ptype,false,turn);
00335 }
00336 osl::Move16 osl::Move::toMove16() const
00337 {
00338 if (isInvalid())
00339 return MOVE16_NONE;
00340 if (isDrop())
00341 return Move16(0x80+(uint16_t)ptype()+((SquareCompressor::compress(to()))<<8));
00342 if (isPromotion())
00343 return Move16(SquareCompressor::compress(from())+(SquareCompressor::compress(to())<<8)+0x8000);
00344 return Move16(SquareCompressor::compress(from())+(SquareCompressor::compress(to())<<8));
00345 }
00346
00347
00348
00349
00350
00351