2352 lines
58 KiB
C++
2352 lines
58 KiB
C++
|
|
/*
|
|||
|
|
----
|
|||
|
|
This file is part of SECONDO.
|
|||
|
|
|
|||
|
|
Copyright (C) 2004, University in Hagen, Department of Computer Science,
|
|||
|
|
Database Systems for New Applications.
|
|||
|
|
|
|||
|
|
SECONDO is free software; you can redistribute it and/or modify
|
|||
|
|
it under the terms of the GNU General Public License as published by
|
|||
|
|
the Free Software Foundation; either version 2 of the License, or
|
|||
|
|
(at your option) any later version.
|
|||
|
|
|
|||
|
|
SECONDO is distributed in the hope that it will be useful,
|
|||
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|||
|
|
GNU General Public License for more details.
|
|||
|
|
|
|||
|
|
You should have received a copy of the GNU General Public License
|
|||
|
|
along with SECONDO; if not, write to the Free Software
|
|||
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|||
|
|
----
|
|||
|
|
|
|||
|
|
//characters [1] verbatim: [\verb@] [@]
|
|||
|
|
//paragraph [1] title: [{\Large \bf ] [}]
|
|||
|
|
|
|||
|
|
|
|||
|
|
[1] chess Algebra
|
|||
|
|
|
|||
|
|
20070104 A. Behrendt Operator movingpoints
|
|||
|
|
20070121 (stream(tuple (Piece: string IsWhite: bool Route:mpoint))) wird erzeugt.
|
|||
|
|
Rochade funktioniert, Bauernwandlung noch nicht eingebaut.
|
|||
|
|
Testspiel chess1 getestet, korrekt bis auf Bauernwandlung im letzten Zug.
|
|||
|
|
|
|||
|
|
1 Defines and includes
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
#include "Algebra.h"
|
|||
|
|
#include "NestedList.h"
|
|||
|
|
#include "QueryProcessor.h"
|
|||
|
|
#include "StandardTypes.h"
|
|||
|
|
#include <iostream>
|
|||
|
|
#include <string>
|
|||
|
|
#include <sstream>
|
|||
|
|
#include "chessTypes.h"
|
|||
|
|
#include "pgnparser.h"
|
|||
|
|
|
|||
|
|
#include "TypeMapUtils.h"
|
|||
|
|
#include "Symbols.h"
|
|||
|
|
|
|||
|
|
#include "Algebras/Temporal/TemporalAlgebra.h"
|
|||
|
|
|
|||
|
|
//using namespace symbols;
|
|||
|
|
using namespace mappings;
|
|||
|
|
|
|||
|
|
using namespace temporalalgebra;
|
|||
|
|
using namespace std;
|
|||
|
|
|
|||
|
|
const std::string MATERIAL="material";
|
|||
|
|
const std::string STRING="string";
|
|||
|
|
const std::string POSITION="position";
|
|||
|
|
const std::string INT = "int";
|
|||
|
|
const std::string BOOL = "bool";
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
extern NestedList* nl;
|
|||
|
|
extern QueryProcessor *qp;
|
|||
|
|
|
|||
|
|
namespace ChessAlgebra
|
|||
|
|
{
|
|||
|
|
#define readIntValue(var, list)\
|
|||
|
|
if ( nl->IsAtom( list ) && nl->AtomType( list ) == IntType )\
|
|||
|
|
var = nl->IntValue( list );\
|
|||
|
|
else\
|
|||
|
|
{\
|
|||
|
|
string liststr;\
|
|||
|
|
nl->WriteToString(liststr, list );\
|
|||
|
|
ErrorReporter::ReportError( "Error: Expected an "\
|
|||
|
|
"integer value at " + liststr + "." );\
|
|||
|
|
correct = false;\
|
|||
|
|
return SetWord( Address( 0 ) );\
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#define readStringValue(var, list)\
|
|||
|
|
if ( nl->IsAtom( list ) && nl->AtomType( list ) == StringType )\
|
|||
|
|
var = nl->StringValue( list );\
|
|||
|
|
else\
|
|||
|
|
{\
|
|||
|
|
string liststr;\
|
|||
|
|
nl->WriteToString(liststr, list );\
|
|||
|
|
ErrorReporter::ReportError( "Error: Expected a"\
|
|||
|
|
" string value at " + liststr + "." );\
|
|||
|
|
correct = false;\
|
|||
|
|
return SetWord( Address( 0 ) );\
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#define readBoolValue(var, list)\
|
|||
|
|
if ( nl->IsAtom( list ) && nl->AtomType( list ) == BoolType )\
|
|||
|
|
var = nl->BoolValue( list );\
|
|||
|
|
else\
|
|||
|
|
{\
|
|||
|
|
string liststr;\
|
|||
|
|
nl->WriteToString(liststr, list );\
|
|||
|
|
ErrorReporter::ReportError( "Error: Expected a"\
|
|||
|
|
" bool value at " + liststr + "." );\
|
|||
|
|
correct = false;\
|
|||
|
|
return SetWord( Address( 0 ) );\
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#define returnError(errstr)\
|
|||
|
|
ErrorReporter::ReportError( errstr );\
|
|||
|
|
correct = false;\
|
|||
|
|
return SetWord( Address( 0 ) )
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
2 Type Constructors
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
2.1 Type Constructor material
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
ListExpr
|
|||
|
|
MaterialProp()
|
|||
|
|
{
|
|||
|
|
return (
|
|||
|
|
nl->TwoElemList(
|
|||
|
|
nl->FiveElemList(
|
|||
|
|
nl->StringAtom( "Signature" ),
|
|||
|
|
nl->StringAtom( "Example Type List" ),
|
|||
|
|
nl->StringAtom( "List Rep" ),
|
|||
|
|
nl->StringAtom( "Example List" ),
|
|||
|
|
nl->StringAtom( "Remarks" ) ),
|
|||
|
|
nl->FiveElemList(
|
|||
|
|
nl->StringAtom( "-> DATA" ),
|
|||
|
|
nl->StringAtom( "material" ),
|
|||
|
|
nl->StringAtom( "(int int ... int) (12 int values)" ),
|
|||
|
|
nl->StringAtom( "(8 2 2 2 1 1 8 2 2 2 1 1)" ),
|
|||
|
|
nl->StringAtom( "..." )
|
|||
|
|
)
|
|||
|
|
)
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr
|
|||
|
|
OutMaterial( ListExpr typeInfo, Word value )
|
|||
|
|
{
|
|||
|
|
Material * mat = ( Material* ) ( value.addr );
|
|||
|
|
ListExpr outlist;
|
|||
|
|
if ( mat->IsDefined() )
|
|||
|
|
{
|
|||
|
|
outlist = nl->Cons(
|
|||
|
|
nl->TwoElemList(
|
|||
|
|
nl->StringAtom( DecodeAgent( BLACK_KING ) ),
|
|||
|
|
nl->IntAtom( mat->Count( DecodeAgent( BLACK_KING ) ) )
|
|||
|
|
),
|
|||
|
|
nl->TheEmptyList()
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
for ( int i = BLACK_QUEEN; i >= WHITE_PAWN; i-- )
|
|||
|
|
{
|
|||
|
|
outlist = nl->Cons(
|
|||
|
|
nl->TwoElemList(
|
|||
|
|
nl->StringAtom( DecodeAgent( i ) ),
|
|||
|
|
nl->IntAtom( mat->Count( DecodeAgent( i ) ) )
|
|||
|
|
),
|
|||
|
|
outlist );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
return nl->SymbolAtom( "undef" );
|
|||
|
|
|
|||
|
|
return ( outlist );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
InMaterial(
|
|||
|
|
const ListExpr typeInfo, const ListExpr instance,
|
|||
|
|
const int errorPos, ListExpr & errorInfo, bool & correct )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( instance ) == 12 )
|
|||
|
|
{
|
|||
|
|
char agents[ 12 ];
|
|||
|
|
ListExpr current = nl->First( instance );
|
|||
|
|
ListExpr rest = nl->Rest( instance );
|
|||
|
|
|
|||
|
|
if ( nl->IsAtom( current ) && nl->AtomType( current ) == IntType )
|
|||
|
|
agents[ 0 ] = nl->IntValue( current );
|
|||
|
|
else if ( ( nl->ListLength( current ) == 2 )
|
|||
|
|
&& ( nl->IsAtom( nl->Second( current ) ) )
|
|||
|
|
&& ( nl->AtomType( nl->Second( current ) ) ) == IntType )
|
|||
|
|
agents[ 0 ] = nl->IntValue( nl->Second( current ) );
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expected list of type\n"
|
|||
|
|
"(int ... int) or ((string int) ... (string int))." );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
for ( int i = 1; i < 12; i++ )
|
|||
|
|
{
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
if ( nl->IsAtom( current ) && nl->AtomType( current ) == IntType )
|
|||
|
|
agents[ i ] = nl->IntValue( current );
|
|||
|
|
else if ( ( nl->ListLength( current ) == 2 )
|
|||
|
|
&& ( nl->IsAtom( nl->Second( current ) ) )
|
|||
|
|
&& ( nl->AtomType( nl->Second( current ) ) ) == IntType )
|
|||
|
|
agents[ i ] = nl->IntValue( nl->Second( current ) );
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expected list of type\n"
|
|||
|
|
"(int ... int) or ((string int) ... (string int)).\n"
|
|||
|
|
"(string value will be ignored)" );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
cout << "OK" << endl;
|
|||
|
|
correct = true;
|
|||
|
|
Material * newmat = new Material ( agents );
|
|||
|
|
return SetWord( newmat );
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expect list with 12 elements of type\n"
|
|||
|
|
"int or (string int)." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void *
|
|||
|
|
CastMaterial( void * addr )
|
|||
|
|
{
|
|||
|
|
return ( new ( addr ) Material );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
CreateMaterial( const ListExpr typeInfo )
|
|||
|
|
{
|
|||
|
|
return ( SetWord( new Material( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ) ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
DeleteMaterial( const ListExpr typeInfo, Word & w )
|
|||
|
|
{
|
|||
|
|
( ( Material * ) w.addr ) ->DeleteIfAllowed();
|
|||
|
|
w.addr = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
CloseMaterial( const ListExpr typeInfo, Word & w )
|
|||
|
|
{
|
|||
|
|
( ( Material * ) w.addr ) ->DeleteIfAllowed();
|
|||
|
|
w.addr = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
CloneMaterial( const ListExpr typeInfo, const Word & w )
|
|||
|
|
{
|
|||
|
|
return SetWord( ( ( Material * ) w.addr ) ->Clone() );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
SizeOfMaterial()
|
|||
|
|
{
|
|||
|
|
return sizeof( Material );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool
|
|||
|
|
MaterialType( ListExpr type, ListExpr & errorInfo )
|
|||
|
|
{
|
|||
|
|
return ( nl->IsEqual( type, "material" ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
2.2 Type Constructor move
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
ListExpr
|
|||
|
|
MoveProp()
|
|||
|
|
{
|
|||
|
|
return (
|
|||
|
|
nl->TwoElemList(
|
|||
|
|
nl->FiveElemList(
|
|||
|
|
nl->StringAtom( "Signature" ),
|
|||
|
|
nl->StringAtom( "Example Type List" ),
|
|||
|
|
nl->StringAtom( "List Rep" ),
|
|||
|
|
nl->StringAtom( "Example List" ),
|
|||
|
|
nl->StringAtom( "Remarks" ) ),
|
|||
|
|
nl->FiveElemList(
|
|||
|
|
nl->StringAtom( "-> DATA" ),
|
|||
|
|
nl->StringAtom( "(move)" ),
|
|||
|
|
nl->StringAtom( "(int string string string"
|
|||
|
|
" int string int bool)" ),
|
|||
|
|
nl->StringAtom( "(3 \"Pawn\" \"none\" \"b\" 2 \"b\" 4 FALSE)" ),
|
|||
|
|
nl->StringAtom( "move, agent, capt. startpos, endpos, check" )
|
|||
|
|
)
|
|||
|
|
)
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr
|
|||
|
|
OutMove( ListExpr typeInfo, Word value )
|
|||
|
|
{
|
|||
|
|
Move * move = ( Move* ) ( value.addr );
|
|||
|
|
ListExpr outlist;
|
|||
|
|
if ( move->IsDefined() )
|
|||
|
|
{
|
|||
|
|
outlist = nl->Cons( nl->BoolAtom( move->IsCheck() ), nl->TheEmptyList() );
|
|||
|
|
outlist = nl->Cons( nl->IntAtom( move->GetEndRow() ), outlist );
|
|||
|
|
outlist = nl->Cons( nl->StringAtom( move->GetEndFile() ), outlist );
|
|||
|
|
outlist = nl->Cons( nl->IntAtom( move->GetStartRow() ), outlist );
|
|||
|
|
outlist = nl->Cons( nl->StringAtom( move->GetStartFile() ), outlist );
|
|||
|
|
outlist = nl->Cons( nl->StringAtom( move->GetCaptured() ), outlist );
|
|||
|
|
outlist = nl->Cons( nl->StringAtom( move->GetAgent() ), outlist );
|
|||
|
|
outlist = nl->Cons( nl->IntAtom( move->GetMoveNumber() ), outlist );
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
return nl->SymbolAtom( "undef" );
|
|||
|
|
|
|||
|
|
return ( outlist );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
InMove(
|
|||
|
|
const ListExpr typeInfo, const ListExpr instance,
|
|||
|
|
const int errorPos, ListExpr & errorInfo, bool & correct )
|
|||
|
|
{
|
|||
|
|
cout << "InMove..." << endl;
|
|||
|
|
if ( nl->ListLength( instance ) == 8 )
|
|||
|
|
{
|
|||
|
|
int moveNumber, startRow, endRow;
|
|||
|
|
string agent, captured, startFile, endFile;
|
|||
|
|
bool check;
|
|||
|
|
|
|||
|
|
ListExpr current = nl->First( instance );
|
|||
|
|
ListExpr rest = nl->Rest( instance );
|
|||
|
|
readIntValue( moveNumber, current )
|
|||
|
|
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
readStringValue( agent, current )
|
|||
|
|
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
readStringValue( captured, current )
|
|||
|
|
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
readStringValue( startFile, current )
|
|||
|
|
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
readIntValue( startRow, current )
|
|||
|
|
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
readStringValue( endFile, current )
|
|||
|
|
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
readIntValue( endRow, current )
|
|||
|
|
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
readBoolValue( check, current )
|
|||
|
|
|
|||
|
|
correct = true;
|
|||
|
|
Move * newmove = new Move ( moveNumber, agent, captured,
|
|||
|
|
startFile, startRow, endFile, endRow,
|
|||
|
|
check );
|
|||
|
|
return SetWord( newmove );
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expected list of type\n"
|
|||
|
|
"(int string string string int string int bool)." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void *
|
|||
|
|
CastMove( void * addr )
|
|||
|
|
{
|
|||
|
|
return ( new ( addr ) Move );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
CreateMove( const ListExpr typeInfo )
|
|||
|
|
{
|
|||
|
|
return ( SetWord( new Move( 0, "none", "none", "a", 1, "a", 1, false ) ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
DeleteMove( const ListExpr typeInfo, Word & w )
|
|||
|
|
{
|
|||
|
|
( ( Move * ) w.addr ) ->DeleteIfAllowed();
|
|||
|
|
w.addr = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
CloseMove( const ListExpr typeInfo, Word & w )
|
|||
|
|
{
|
|||
|
|
( ( Move * ) w.addr ) ->DeleteIfAllowed();
|
|||
|
|
w.addr = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
CloneMove( const ListExpr typeInfo, const Word & w )
|
|||
|
|
{
|
|||
|
|
return SetWord( ( ( Move * ) w.addr ) ->Clone() );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
SizeOfMove()
|
|||
|
|
{
|
|||
|
|
return sizeof( Move );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool
|
|||
|
|
MoveType( ListExpr type, ListExpr & errorInfo )
|
|||
|
|
{
|
|||
|
|
return ( nl->IsEqual( type, "chessmove" ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
2.3 Type Constructor position
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
ListExpr
|
|||
|
|
PositionProp()
|
|||
|
|
{
|
|||
|
|
return (
|
|||
|
|
nl->TwoElemList(
|
|||
|
|
nl->FiveElemList(
|
|||
|
|
nl->StringAtom( "Signature" ),
|
|||
|
|
nl->StringAtom( "Example Type List" ),
|
|||
|
|
nl->StringAtom( "List Rep" ),
|
|||
|
|
nl->StringAtom( "Example List" ),
|
|||
|
|
nl->StringAtom( "Remarks" ) ),
|
|||
|
|
nl->FiveElemList(
|
|||
|
|
nl->StringAtom( "-> DATA" ),
|
|||
|
|
nl->StringAtom( "position" ),
|
|||
|
|
nl->StringAtom( "(int ((string string int)...))" ),
|
|||
|
|
nl->StringAtom( "(43 ((\"King\" \"b\" 5)(\"king\" \"h\" 7)))" ),
|
|||
|
|
nl->StringAtom( "..." )
|
|||
|
|
)
|
|||
|
|
)
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
ListExpr
|
|||
|
|
OutPosition( ListExpr typeInfo, Word value )
|
|||
|
|
{
|
|||
|
|
Position * pos = ( Position* ) ( value.addr );
|
|||
|
|
ListExpr outlist;
|
|||
|
|
if ( pos->IsDefined() )
|
|||
|
|
{
|
|||
|
|
int moveNumber = pos->GetMoveNumber();
|
|||
|
|
ListExpr agentList, agentRow;
|
|||
|
|
|
|||
|
|
bool firstRow = true;
|
|||
|
|
agentList = nl->TheEmptyList();
|
|||
|
|
for ( int row = 1; row <= 8; row++ )
|
|||
|
|
{
|
|||
|
|
bool firstAgent = true;
|
|||
|
|
agentRow = nl->TheEmptyList();
|
|||
|
|
for ( char file = 'h'; file >= 'a'; file-- )
|
|||
|
|
{
|
|||
|
|
if ( firstAgent )
|
|||
|
|
{
|
|||
|
|
agentRow = nl->Cons(
|
|||
|
|
nl->StringAtom( pos->GetAgentShort( file, row ) ) ,
|
|||
|
|
nl->TheEmptyList() );
|
|||
|
|
firstAgent = false;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
agentRow = nl->Cons(
|
|||
|
|
nl->StringAtom( pos->GetAgentShort( file, row ) ) ,
|
|||
|
|
agentRow );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if ( firstRow )
|
|||
|
|
{
|
|||
|
|
agentList = nl->Cons( agentRow , nl->TheEmptyList() );
|
|||
|
|
firstRow = false;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
agentList = nl->Cons( agentRow , agentList );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
outlist = nl->TwoElemList( nl->IntAtom( moveNumber ), agentList );
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
return nl->SymbolAtom( "undef" );
|
|||
|
|
|
|||
|
|
return ( outlist );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
InPosition(
|
|||
|
|
const ListExpr typeInfo, const ListExpr instance,
|
|||
|
|
const int errorPos, ListExpr & errorInfo, bool & correct )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( instance ) == 2 )
|
|||
|
|
{
|
|||
|
|
ListExpr first, second, current;
|
|||
|
|
string agent;
|
|||
|
|
int moveNumber, row;
|
|||
|
|
|
|||
|
|
first = nl->First( instance );
|
|||
|
|
second = nl->Second( instance );
|
|||
|
|
|
|||
|
|
readIntValue( moveNumber, first )
|
|||
|
|
Position * newpos = new Position ( moveNumber );
|
|||
|
|
|
|||
|
|
ListExpr rowList;
|
|||
|
|
if ( nl->ListLength( second ) == 8 )
|
|||
|
|
{
|
|||
|
|
int row = 8;
|
|||
|
|
while ( !nl->IsEmpty( second ) )
|
|||
|
|
{
|
|||
|
|
char file = 'a';
|
|||
|
|
rowList = nl->First( second );
|
|||
|
|
second = nl->Rest( second );
|
|||
|
|
if ( nl->ListLength( rowList ) == 8 )
|
|||
|
|
{
|
|||
|
|
while ( !nl->IsEmpty( rowList ) )
|
|||
|
|
{
|
|||
|
|
current = nl->First( rowList );
|
|||
|
|
rowList = nl->Rest( rowList );
|
|||
|
|
readStringValue( agent, current )
|
|||
|
|
int err = 0;
|
|||
|
|
if ( agent != DecodeAgentShort( NONE ) )
|
|||
|
|
err = newpos->AddAgent( agent, file, row );
|
|||
|
|
if ( err == -2 )
|
|||
|
|
{
|
|||
|
|
ostringstream errmsg;
|
|||
|
|
errmsg << "Error: Agent type '" << agent << "' not found.";
|
|||
|
|
returnError( errmsg.str() );
|
|||
|
|
}
|
|||
|
|
file++;
|
|||
|
|
}
|
|||
|
|
row--;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expected list of type\n"
|
|||
|
|
"(int ((string ... string)...(string ... string))),\n"
|
|||
|
|
"which defines the agents on all 64 squares." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
string file;
|
|||
|
|
while ( !nl->IsEmpty( second ) )
|
|||
|
|
{
|
|||
|
|
current = nl->First( second );
|
|||
|
|
second = nl->Rest( second );
|
|||
|
|
if ( nl->ListLength( current ) == 3 )
|
|||
|
|
{
|
|||
|
|
readStringValue( agent, nl->First( current ) )
|
|||
|
|
readStringValue( file, nl->Second( current ) )
|
|||
|
|
readIntValue( row, nl->Third( current ) )
|
|||
|
|
int err = newpos->AddAgent( agent, file[ 0 ], row );
|
|||
|
|
if ( err )
|
|||
|
|
{
|
|||
|
|
ostringstream errmsg;
|
|||
|
|
if ( err == -1 )
|
|||
|
|
{
|
|||
|
|
errmsg << "Error: Can't store agent '"
|
|||
|
|
<< agent
|
|||
|
|
<< "' at square " << file << row
|
|||
|
|
<< ", square already contains an agent of type '"
|
|||
|
|
<< newpos->GetAgent( file[ 0 ], row )
|
|||
|
|
<< "'.";
|
|||
|
|
}
|
|||
|
|
else if ( err == -2 )
|
|||
|
|
{
|
|||
|
|
errmsg << "Error: Agent type '" << agent << "' not found.";
|
|||
|
|
}
|
|||
|
|
returnError( errmsg.str() );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expected list of type\n"
|
|||
|
|
"(int ((string string int)...(string string int)))." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
correct = true;
|
|||
|
|
return SetWord( newpos );
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expected list of type\n"
|
|||
|
|
"(int ((string string int)...(string string int))) or\n"
|
|||
|
|
"(int ((string ... string)...(string ... string)))." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void *
|
|||
|
|
CastPosition( void * addr )
|
|||
|
|
{
|
|||
|
|
return ( new ( addr ) Position );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
CreatePosition( const ListExpr typeInfo )
|
|||
|
|
{
|
|||
|
|
return ( SetWord( new Position( 0 ) ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
DeletePosition( const ListExpr typeInfo, Word & w )
|
|||
|
|
{
|
|||
|
|
( ( Position * ) w.addr ) ->DeleteIfAllowed();
|
|||
|
|
w.addr = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
ClosePosition( const ListExpr typeInfo, Word & w )
|
|||
|
|
{
|
|||
|
|
( ( Position * ) w.addr ) ->DeleteIfAllowed();
|
|||
|
|
w.addr = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
ClonePosition( const ListExpr typeInfo, const Word & w )
|
|||
|
|
{
|
|||
|
|
return SetWord( ( ( Position * ) w.addr ) ->Clone() );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
SizeOfPosition()
|
|||
|
|
{
|
|||
|
|
return sizeof( Position );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool
|
|||
|
|
PositionType( ListExpr type, ListExpr & errorInfo )
|
|||
|
|
{
|
|||
|
|
return ( nl->IsEqual( type, "position" ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
2.4 Type Constructor Chessgame
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
ListExpr
|
|||
|
|
ChessgameProp()
|
|||
|
|
{
|
|||
|
|
return (
|
|||
|
|
nl->TwoElemList(
|
|||
|
|
nl->FiveElemList(
|
|||
|
|
nl->StringAtom( "Signature" ),
|
|||
|
|
nl->StringAtom( "Example Type List" ),
|
|||
|
|
nl->StringAtom( "List Rep" ),
|
|||
|
|
nl->StringAtom( "Example List" ),
|
|||
|
|
nl->StringAtom( "Remarks" ) ),
|
|||
|
|
nl->FiveElemList(
|
|||
|
|
nl->StringAtom( "-> DATA" ),
|
|||
|
|
nl->StringAtom( "( chessgame ) " ),
|
|||
|
|
nl->StringAtom( "() " ),
|
|||
|
|
nl->StringAtom( "() " ),
|
|||
|
|
nl->StringAtom( "" )
|
|||
|
|
)
|
|||
|
|
)
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr
|
|||
|
|
OutChessgame( ListExpr typeInfo, Word value )
|
|||
|
|
{
|
|||
|
|
Chessgame * game = ( Chessgame* ) ( value.addr );
|
|||
|
|
ListExpr outlist;
|
|||
|
|
|
|||
|
|
if ( game->IsDefined() )
|
|||
|
|
{
|
|||
|
|
ListExpr metainfoList, movesList;
|
|||
|
|
|
|||
|
|
// build metainfoList;
|
|||
|
|
if ( !game->GetMetainfoCount() )
|
|||
|
|
metainfoList = nl->TheEmptyList();
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
bool firstListEntry = true;
|
|||
|
|
for ( int i = ( ( game->GetMetainfoCount() ) - 1 ); i >= 0; i-- )
|
|||
|
|
{
|
|||
|
|
MetainfoEntry metainfo = game->GetMetainfoEntry( i );
|
|||
|
|
|
|||
|
|
/* do not print EventDate and ECO if respective values are empty. Date,
|
|||
|
|
Event, White, Black, Site, Round and Result (STR-Tags) will always be
|
|||
|
|
printed, even if they are originaly not contained in the pgn-file.
|
|||
|
|
All other tags will only be printed, if they are contained in the
|
|||
|
|
respective pgn file
|
|||
|
|
*/
|
|||
|
|
string key ( metainfo.key );
|
|||
|
|
if ( ( metainfo.value[ 0 ] != '\0' ) ||
|
|||
|
|
( ( key != "EventDate" ) &&
|
|||
|
|
( key != "ECO" ) )
|
|||
|
|
)
|
|||
|
|
{
|
|||
|
|
if ( firstListEntry )
|
|||
|
|
{
|
|||
|
|
metainfoList = nl->Cons( nl->TwoElemList(
|
|||
|
|
nl->StringAtom( metainfo.key ),
|
|||
|
|
nl->StringAtom( metainfo.value )
|
|||
|
|
), nl->TheEmptyList() );
|
|||
|
|
firstListEntry = false;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
metainfoList = nl->Cons( nl->TwoElemList(
|
|||
|
|
nl->StringAtom( metainfo.key ),
|
|||
|
|
nl->StringAtom( metainfo.value )
|
|||
|
|
), metainfoList );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// build movesList;
|
|||
|
|
if ( game->GetMovesCount() == 0 )
|
|||
|
|
movesList = nl->TheEmptyList();
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
bool firstListEntry = true;
|
|||
|
|
for ( int i = ( game->GetMovesCount() ); i > 0; i-- )
|
|||
|
|
{
|
|||
|
|
ListExpr movelist;
|
|||
|
|
Move move;
|
|||
|
|
game->GetMove( move, i );
|
|||
|
|
|
|||
|
|
// build movelist
|
|||
|
|
movelist = nl->Cons( nl->StringAtom( game->GetPGN( i ) ),
|
|||
|
|
nl->TheEmptyList() );
|
|||
|
|
movelist = nl->Cons( nl->BoolAtom( move.IsCheck() ), movelist );
|
|||
|
|
movelist = nl->Cons( nl->IntAtom( move.GetEndRow() ), movelist );
|
|||
|
|
movelist = nl->Cons( nl->StringAtom( move.GetEndFile() ), movelist );
|
|||
|
|
movelist = nl->Cons( nl->IntAtom( move.GetStartRow() ), movelist );
|
|||
|
|
movelist = nl->Cons( nl->StringAtom( move.GetStartFile() ), movelist);
|
|||
|
|
movelist = nl->Cons( nl->StringAtom( move.GetCaptured() ), movelist );
|
|||
|
|
movelist = nl->Cons( nl->StringAtom( move.GetAgent() ), movelist );
|
|||
|
|
|
|||
|
|
if ( firstListEntry )
|
|||
|
|
{
|
|||
|
|
movesList = nl->Cons( movelist, nl->TheEmptyList() );
|
|||
|
|
firstListEntry = false;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
movesList = nl->Cons( movelist, movesList );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
outlist = nl->TwoElemList( metainfoList, movesList );
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
return nl->SymbolAtom( "undef" );
|
|||
|
|
|
|||
|
|
return ( outlist );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
InChessgame(
|
|||
|
|
const ListExpr typeInfo, const ListExpr instance,
|
|||
|
|
const int errorPos, ListExpr & errorInfo, bool & correct )
|
|||
|
|
{
|
|||
|
|
Chessgame * game = new Chessgame( 0, 0 );
|
|||
|
|
if ( nl->ListLength( instance ) == 2 )
|
|||
|
|
{
|
|||
|
|
ListExpr current, rest;
|
|||
|
|
|
|||
|
|
// read metainfos
|
|||
|
|
rest = nl->First( instance );
|
|||
|
|
while ( !nl->IsEmpty( rest ) )
|
|||
|
|
{
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
|
|||
|
|
if ( nl->ListLength( current ) == 2 )
|
|||
|
|
{
|
|||
|
|
string key, value;
|
|||
|
|
readStringValue( key, nl->First( current ) )
|
|||
|
|
readStringValue( value, nl->Second( current ) )
|
|||
|
|
|
|||
|
|
// add metainfo entry
|
|||
|
|
game->AddMetainfoEntry( key, value );
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expected list of type\n"
|
|||
|
|
"((string string)...(string string))." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// read moves
|
|||
|
|
rest = nl->Second( instance );
|
|||
|
|
while ( !nl->IsEmpty( rest ) )
|
|||
|
|
{
|
|||
|
|
current = nl->First( rest );
|
|||
|
|
rest = nl->Rest( rest );
|
|||
|
|
|
|||
|
|
if ( nl->ListLength( current ) == 8 )
|
|||
|
|
{
|
|||
|
|
string startFile, endFile, pgn;
|
|||
|
|
int startRow, endRow;
|
|||
|
|
|
|||
|
|
// first value is ignored
|
|||
|
|
ListExpr current2 = nl->First( current );
|
|||
|
|
ListExpr rest2 = nl->Rest( current );
|
|||
|
|
|
|||
|
|
// second value is ignored
|
|||
|
|
current2 = nl->First( rest2 );
|
|||
|
|
rest2 = nl->Rest( rest2 );
|
|||
|
|
|
|||
|
|
// read startfile
|
|||
|
|
current2 = nl->First( rest2 );
|
|||
|
|
rest2 = nl->Rest( rest2 );
|
|||
|
|
readStringValue( startFile, current2 )
|
|||
|
|
|
|||
|
|
// read startrow
|
|||
|
|
current2 = nl->First( rest2 );
|
|||
|
|
rest2 = nl->Rest( rest2 );
|
|||
|
|
readIntValue( startRow, current2 )
|
|||
|
|
|
|||
|
|
// read endfile
|
|||
|
|
current2 = nl->First( rest2 );
|
|||
|
|
rest2 = nl->Rest( rest2 );
|
|||
|
|
readStringValue( endFile, current2 )
|
|||
|
|
|
|||
|
|
// read endrow
|
|||
|
|
current2 = nl->First( rest2 );
|
|||
|
|
rest2 = nl->Rest( rest2 );
|
|||
|
|
readIntValue( endRow, current2 )
|
|||
|
|
|
|||
|
|
// check state value is ignored
|
|||
|
|
current2 = nl->First( rest2 );
|
|||
|
|
rest2 = nl->Rest( rest2 );
|
|||
|
|
|
|||
|
|
// read pgn-notation
|
|||
|
|
current2 = nl->First( rest2 );
|
|||
|
|
rest2 = nl->Rest( rest2 );
|
|||
|
|
readStringValue( pgn, current2 )
|
|||
|
|
|
|||
|
|
// add move
|
|||
|
|
game->AddMove( startFile[ 0 ], startRow, endFile[ 0 ], endRow, pgn );
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expected list of type\n"
|
|||
|
|
"((string string string int string "
|
|||
|
|
"int bool string string)...(...))." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
game->SortMetainfos();
|
|||
|
|
correct = true;
|
|||
|
|
return SetWord( game );
|
|||
|
|
}
|
|||
|
|
else if ( ( nl->ListLength( instance ) == 1 )
|
|||
|
|
&& ( nl->IsAtom( nl->First( instance ) )
|
|||
|
|
&& nl->AtomType( nl->First( instance ) ) == TextType ) )
|
|||
|
|
{
|
|||
|
|
string filename;
|
|||
|
|
nl->Text2String( nl->First( instance ), filename );
|
|||
|
|
ifstream * file = new ifstream( filename.c_str() );
|
|||
|
|
if ( file )
|
|||
|
|
{
|
|||
|
|
game = ParseFile( file );
|
|||
|
|
if ( game )
|
|||
|
|
{
|
|||
|
|
correct = true;
|
|||
|
|
return SetWord( game );
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError( "Error while parsing file " + filename + "." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError( "Error: File " + filename + " not found." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
returnError(
|
|||
|
|
"Error: Wrong list format. Expected list of type\n"
|
|||
|
|
"(metainfo_list move_list)." );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void *
|
|||
|
|
CastChessgame( void * addr )
|
|||
|
|
{
|
|||
|
|
return ( new ( addr ) Chessgame );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
CreateChessgame( const ListExpr typeInfo )
|
|||
|
|
{
|
|||
|
|
return ( SetWord( new Chessgame( 0, 0 ) ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
DeleteChessgame( const ListExpr typeInfo, Word & w )
|
|||
|
|
{
|
|||
|
|
( ( Chessgame * ) w.addr ) ->DeleteIfAllowed();
|
|||
|
|
w.addr = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void
|
|||
|
|
CloseChessgame( const ListExpr typeInfo, Word & w )
|
|||
|
|
{
|
|||
|
|
( ( Chessgame * ) w.addr ) ->DeleteIfAllowed();
|
|||
|
|
w.addr = 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Word
|
|||
|
|
CloneChessgame( const ListExpr typeInfo, const Word & w )
|
|||
|
|
{
|
|||
|
|
return SetWord( ( ( Chessgame * ) w.addr ) ->Clone() );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
SizeOfChessgame()
|
|||
|
|
{
|
|||
|
|
return sizeof( Chessgame );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool
|
|||
|
|
ChessgameType( ListExpr type, ListExpr & errorInfo )
|
|||
|
|
{
|
|||
|
|
return ( nl->IsEqual( type, "chessgame" ) );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool
|
|||
|
|
OpenChessgame(
|
|||
|
|
SmiRecord & valueRecord, size_t & offset,
|
|||
|
|
const ListExpr typeInfo, Word & value )
|
|||
|
|
{
|
|||
|
|
Chessgame * game;
|
|||
|
|
game = ( Chessgame* ) Attribute::Open( valueRecord, offset, typeInfo );
|
|||
|
|
value = SetWord( game );
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
bool
|
|||
|
|
SaveChessgame(
|
|||
|
|
SmiRecord & valueRecord, size_t & offset,
|
|||
|
|
const ListExpr typeInfo, Word & value )
|
|||
|
|
{
|
|||
|
|
Chessgame * p = ( Chessgame * ) value.addr;
|
|||
|
|
Attribute::Save( valueRecord, offset, typeInfo, p );
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3 Operators
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.1 Operator readpgn
|
|||
|
|
|
|||
|
|
reads a pgn file and returns a realtion of tuples, each containing only one
|
|||
|
|
attribute of type games
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string readpgnSpec =
|
|||
|
|
"( " "( " "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>text -> stream (game)</text--->"
|
|||
|
|
"<text>readpgn( _ )</text--->"
|
|||
|
|
"<text>Reads a file and returns a stream of games</text--->"
|
|||
|
|
"<text>query readpgn(\"ICCF2006.pgn\")</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int readpgnValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
|
|||
|
|
ifstream * file;
|
|||
|
|
const char* filename;
|
|||
|
|
FText* fn;
|
|||
|
|
Chessgame* game;
|
|||
|
|
switch ( message )
|
|||
|
|
{
|
|||
|
|
case OPEN:
|
|||
|
|
fn = ( ( FText * ) args[ 0 ].addr );
|
|||
|
|
filename = fn->Get();
|
|||
|
|
file = new ifstream( filename );
|
|||
|
|
local.addr = file;
|
|||
|
|
cout << "Parsing file '" << filename << "' - please wait..." << endl;
|
|||
|
|
return 0;
|
|||
|
|
case REQUEST:
|
|||
|
|
|
|||
|
|
file = ( ifstream* ) local.addr;
|
|||
|
|
if(!(*file)){
|
|||
|
|
return CANCEL;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ( file->is_open() )
|
|||
|
|
{
|
|||
|
|
if ( !file->eof() )
|
|||
|
|
game = ParseFile( file );
|
|||
|
|
else
|
|||
|
|
return CANCEL;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
ErrorReporter::ReportError( "File not open." );
|
|||
|
|
|
|||
|
|
if ( game != NULL )
|
|||
|
|
{
|
|||
|
|
cout << ".";
|
|||
|
|
result.addr = game;
|
|||
|
|
return YIELD;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
cout << endl << "Finished parsing file.";
|
|||
|
|
return CANCEL;
|
|||
|
|
}
|
|||
|
|
case CLOSE:
|
|||
|
|
file = ( ifstream* ) local.addr;
|
|||
|
|
file->close();
|
|||
|
|
cout << endl;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr readpgnTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 1 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg = nl->First( args );
|
|||
|
|
if ( nl->IsAtom( arg ) && nl->IsEqual( arg, "text" ) )
|
|||
|
|
{
|
|||
|
|
return nl->TwoElemList(
|
|||
|
|
nl->SymbolAtom( "stream" ),
|
|||
|
|
nl->SymbolAtom( "chessgame" ) );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.2 Operators on move type constructor
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string agentSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>move -> string</text--->"
|
|||
|
|
"<text>_ move</text--->"
|
|||
|
|
"<text>Returns agent figure of a move.</text--->"
|
|||
|
|
"<text>query move1 agent</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
const string capturedSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>move -> string</text--->"
|
|||
|
|
"<text>_ move</text--->"
|
|||
|
|
"<text>Returns captured figure of a move.</text--->"
|
|||
|
|
"<text>query move1 captured</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
const string startrowSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>move -> int</text--->"
|
|||
|
|
"<text>_ move</text--->"
|
|||
|
|
"<text>Returns start row of a move.</text--->"
|
|||
|
|
"<text>query move1 startrow</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
const string endrowSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>move -> int</text--->"
|
|||
|
|
"<text>_ move</text--->"
|
|||
|
|
"<text>Returns end row of a move.</text--->"
|
|||
|
|
"<text>query move1 endrow</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
const string startfileSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>move -> string</text--->"
|
|||
|
|
"<text>_ move</text--->"
|
|||
|
|
"<text>Returns start file of a move.</text--->"
|
|||
|
|
"<text>query move1 startfile</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
const string endfileSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>move -> string</text--->"
|
|||
|
|
"<text>_ move</text--->"
|
|||
|
|
"<text>Returns end file of a move.</text--->"
|
|||
|
|
"<text>query move1 endfile</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
const string checkSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>move -> bool</text--->"
|
|||
|
|
"<text>_ move</text--->"
|
|||
|
|
"<text>Returns true, if check was offered.</text--->"
|
|||
|
|
"<text>query move1 check</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
const string capturesSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>move -> bool</text--->"
|
|||
|
|
"<text>_ move</text--->"
|
|||
|
|
"<text>Returns true, if some figure was captured.</text--->"
|
|||
|
|
"<text>query move1 captured</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int agentValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Move * move = ( ( Move* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
STRING_T resultString;
|
|||
|
|
int len = ( move->GetAgent() ).string::copy( resultString, 48, 0 );
|
|||
|
|
resultString[ len ] = '\0';
|
|||
|
|
( ( CcString* ) result.addr ) ->Set( true, &resultString );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int capturedValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Move * move = ( ( Move* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
STRING_T resultString;
|
|||
|
|
int len = ( move->GetCaptured() ).string::copy( resultString, 48, 0 );
|
|||
|
|
resultString[ len ] = '\0';
|
|||
|
|
( ( CcString* ) result.addr ) ->Set( true, &resultString );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int startrowValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Move * move = ( ( Move* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
( ( CcInt* ) result.addr ) ->Set( true, move->GetStartRow() );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int endrowValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Move * move = ( ( Move* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
( ( CcInt* ) result.addr ) ->Set( true, move->GetEndRow() );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int startfileValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Move * move = ( ( Move* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
STRING_T resultString;
|
|||
|
|
int len = ( move->GetStartFile() ).string::copy( resultString, 48, 0 );
|
|||
|
|
resultString[ len ] = '\0';
|
|||
|
|
( ( CcString* ) result.addr ) ->Set( true, &resultString );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int endfileValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Move * move = ( ( Move* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
STRING_T resultString;
|
|||
|
|
int len = ( move->GetEndFile() ).string::copy( resultString, 48, 0 );
|
|||
|
|
resultString[ len ] = '\0';
|
|||
|
|
( ( CcString* ) result.addr ) ->Set( true, &resultString );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int checkValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Move * move = ( ( Move* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
( ( CcBool* ) result.addr ) ->Set( true, move->IsCheck() );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int capturesValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Move * move = ( ( Move* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
( ( CcBool* ) result.addr ) ->Set( true, move->GetCaptures() );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr moveStrTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 1 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg = nl->First( args );
|
|||
|
|
if ( nl->IsEqual( arg, "chessmove" ) )
|
|||
|
|
{
|
|||
|
|
return nl->SymbolAtom( "string" );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr moveIntTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 1 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg = nl->First( args );
|
|||
|
|
if ( nl->IsEqual( arg, "chessmove" ) )
|
|||
|
|
{
|
|||
|
|
return nl->SymbolAtom( "int" );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr moveBoolTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 1 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg = nl->First( args );
|
|||
|
|
if ( nl->IsEqual( arg, "chessmove" ) )
|
|||
|
|
{
|
|||
|
|
return nl->SymbolAtom( "bool" );
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.3 Operator piececount
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
struct piececountInfo : OperatorInfo {
|
|||
|
|
|
|||
|
|
piececountInfo() : OperatorInfo()
|
|||
|
|
{
|
|||
|
|
name = "piececount";
|
|||
|
|
signature = "material x string -> int, position x string -> int";
|
|||
|
|
syntax = "_ piececount[_]";
|
|||
|
|
meaning = "Returns number of respective figures for the given "
|
|||
|
|
"material or position. The regerded figures can be specified "
|
|||
|
|
"by names or by a sequence of their first letter, or the "
|
|||
|
|
"special set constants \"all\", \"white\" and \"black\"";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
const string maps_pc[2][3] = { {MATERIAL, STRING, INT},
|
|||
|
|
{POSITION, STRING, INT} };
|
|||
|
|
|
|||
|
|
static ListExpr
|
|||
|
|
piececount_tm(ListExpr args)
|
|||
|
|
{
|
|||
|
|
return SimpleMaps<2,3>(maps_pc, args);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
piececount_sf( ListExpr args )
|
|||
|
|
{
|
|||
|
|
return SimpleSelect<2,3>(maps_pc, args);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
int piececount_vm( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Material* material = static_cast<Material*>( args[ 0 ].addr );
|
|||
|
|
CcString* value = static_cast<CcString*>( args[ 1 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
|
|||
|
|
static_cast<CcInt*>( result.addr )->Set( true,
|
|||
|
|
material->Count( *value->GetStringval() ) );
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
int piececount_vm2( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Position* pos = static_cast<Position*>( args[ 0 ].addr );
|
|||
|
|
CcString* value = static_cast<CcString*>( args[ 1 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
|
|||
|
|
Material mat;
|
|||
|
|
pos->GetMaterial(&mat);
|
|||
|
|
|
|||
|
|
static_cast<CcInt*>( result.addr )->Set( true,
|
|||
|
|
mat.Count( *value->GetStringval() ) );
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.3 Operators exact equal "(=)"[1] and piecevalue equal "(tilde)" and piecvalue less "(<)"
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
struct equalInfo : OperatorInfo {
|
|||
|
|
|
|||
|
|
equalInfo() : OperatorInfo()
|
|||
|
|
{
|
|||
|
|
name = "=";
|
|||
|
|
signature = "material x material -> bool, position x string -> bool";
|
|||
|
|
syntax = "_ = _";
|
|||
|
|
meaning = "Returns true if both values are exactly equal. In the case "
|
|||
|
|
"of positions the move must not be equal";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
|
|||
|
|
struct approxequalInfo : OperatorInfo {
|
|||
|
|
|
|||
|
|
approxequalInfo() : OperatorInfo()
|
|||
|
|
{
|
|||
|
|
name = "~";
|
|||
|
|
signature = "material x material -> bool, position x string -> bool";
|
|||
|
|
syntax = "_ ~ _";
|
|||
|
|
meaning = "Returns true if both weighted sums of material are equal. "
|
|||
|
|
"In the case of positions the material of the whole board "
|
|||
|
|
"is used.";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
|
|||
|
|
struct lessInfo : OperatorInfo {
|
|||
|
|
|
|||
|
|
lessInfo() : OperatorInfo()
|
|||
|
|
{
|
|||
|
|
name = "<";
|
|||
|
|
signature = "material x material -> bool, position x string -> bool";
|
|||
|
|
syntax = "_ < _";
|
|||
|
|
meaning = "Returns true if the weighted sum of the material, or"
|
|||
|
|
"the material given by the position is less than the other";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.4 Type Mappings
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
const string maps_equal[2][3] = { {MATERIAL, MATERIAL, BOOL},
|
|||
|
|
{POSITION, POSITION, BOOL} };
|
|||
|
|
|
|||
|
|
static ListExpr
|
|||
|
|
equal_tm(ListExpr args)
|
|||
|
|
{
|
|||
|
|
return SimpleMaps<2,3>(maps_equal, args);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int
|
|||
|
|
equal_sf( ListExpr args )
|
|||
|
|
{
|
|||
|
|
return SimpleSelect<2,3>(maps_equal, args);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
template<class T>
|
|||
|
|
int equal_vm( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
T* arg1 = static_cast<T*>( args[0].addr );
|
|||
|
|
T* arg2 = static_cast<T*>( args[1].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
|
|||
|
|
static_cast<CcBool*>( result.addr )->Set( true, arg1->Compare( arg2 ) == 0 );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
template<class T>
|
|||
|
|
int approxequal_vm( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
T* arg1 = static_cast<T*>( args[0].addr );
|
|||
|
|
T* arg2 = static_cast<T*>( args[1].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
|
|||
|
|
static_cast<CcBool*>( result.addr )->Set( true,
|
|||
|
|
arg1->ComparePieceValues( arg2 ) == 0 );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
template<class T>
|
|||
|
|
int less_vm( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
T* arg1 = static_cast<T*>( args[ 0 ].addr );
|
|||
|
|
T* arg2 = static_cast<T*>( args[ 1 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
|
|||
|
|
static_cast<CcBool*>( result.addr )->Set( true,
|
|||
|
|
( arg1->ComparePieceValues( arg2 ) < 0 ) );
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
ListExpr MatMatBoolTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 2 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg1 = nl->First( args );
|
|||
|
|
ListExpr arg2 = nl->Second( args );
|
|||
|
|
if ( nl->IsEqual( arg1, "material" ) && nl->IsEqual( arg2, "material" ) )
|
|||
|
|
return nl->SymbolAtom( "bool" );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.4 Operator pieces
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string piecesSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>material string -> bool</text--->"
|
|||
|
|
"<text>_ pieces</text--->"
|
|||
|
|
"<text>Returns respective material object.</text--->"
|
|||
|
|
"<text>query pos1 pieces</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int piecesValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Position * position = ( ( Position* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
if ( position->IsDefined() )
|
|||
|
|
position->GetMaterial( ( ( Material* ) result.addr ) );
|
|||
|
|
else
|
|||
|
|
( ( Material* ) result.addr ) ->SetDefined( false );
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr piecesTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 1 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg = nl->First( args );
|
|||
|
|
if ( nl->IsEqual( arg, "position" ) )
|
|||
|
|
return nl->SymbolAtom( "material" );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.5 Operator moveNo
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string moveNoSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>move -> int, position -> int</text--->"
|
|||
|
|
"<text>_ moveNo</text--->"
|
|||
|
|
"<text>Returns move number of move or position object.</text--->"
|
|||
|
|
"<text>query move1 moveNo</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int moveNoValueMapM( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Move * move = ( ( Move* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
if ( move->IsDefined() )
|
|||
|
|
( ( CcInt* ) result.addr ) ->Set( true, move->GetMoveNumber() );
|
|||
|
|
else
|
|||
|
|
( ( CcInt* ) result.addr ) ->SetDefined( false );
|
|||
|
|
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
int moveNoValueMapP( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Position * position = ( ( Position* ) args[ 0 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
if ( position->IsDefined() )
|
|||
|
|
( ( CcInt* ) result.addr ) ->Set( true, position->GetMoveNumber() );
|
|||
|
|
else
|
|||
|
|
( ( CcInt* ) result.addr ) ->SetDefined( false );
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr moveNoTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 1 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg = nl->First( args );
|
|||
|
|
if ( ( nl->IsEqual( arg, "chessmove" ) ) ||
|
|||
|
|
( nl->IsEqual( arg, "position" ) ) )
|
|||
|
|
return nl->SymbolAtom( "int" );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ValueMapping moveNoMap[] = { moveNoValueMapM, moveNoValueMapP };
|
|||
|
|
int moveNoSelect( ListExpr args )
|
|||
|
|
{
|
|||
|
|
ListExpr arg = nl->First( args );
|
|||
|
|
if ( nl->IsEqual( arg, "chessmove" ) )
|
|||
|
|
return ( 0 );
|
|||
|
|
if ( nl->IsEqual( arg, "position" ) )
|
|||
|
|
return ( 1 );
|
|||
|
|
return ( -1 ); // This point should never be reached
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.6 Operator range
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string rangeSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>string int string int-> position</text--->"
|
|||
|
|
"<text>_ range[_,_,_,_]</text--->"
|
|||
|
|
"<text>Returns a partial position object.</text--->"
|
|||
|
|
"<text>query pos1 range[\"b\",2,\"g\",7]</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int rangeValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Position * position = ( ( Position* ) args[ 0 ].addr );
|
|||
|
|
CcString * startFile = ( ( CcString* ) args[ 1 ].addr );
|
|||
|
|
CcInt * startRow = ( ( CcInt* ) args[ 2 ].addr );
|
|||
|
|
CcString * endFile = ( ( CcString* ) args[ 3 ].addr );
|
|||
|
|
CcInt * endRow = ( ( CcInt* ) args[ 4 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
position->Range( ( ( Position* ) result.addr ),
|
|||
|
|
startFile->GetValue() [ 0 ], startRow->GetValue(),
|
|||
|
|
endFile->GetValue() [ 0 ], endRow->GetValue() );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr rangeTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 5 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg1 = nl->First( args );
|
|||
|
|
ListExpr arg2 = nl->Second( args );
|
|||
|
|
ListExpr arg3 = nl->Third( args );
|
|||
|
|
ListExpr arg4 = nl->Fourth( args );
|
|||
|
|
ListExpr arg5 = nl->Fifth( args );
|
|||
|
|
if ( ( nl->IsEqual( arg1, "position" ) )
|
|||
|
|
&& nl->IsAtom( arg2 ) && nl->IsEqual( arg2, "string" )
|
|||
|
|
&& nl->IsAtom( arg3 ) && nl->IsEqual( arg3, "int" )
|
|||
|
|
&& nl->IsAtom( arg4 ) && nl->IsEqual( arg4, "string" )
|
|||
|
|
&& nl->IsAtom( arg5 ) && nl->IsEqual( arg5, "int" ) )
|
|||
|
|
return nl->SymbolAtom( "position" );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.7 Operator includes
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string includesSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>position position -> bool</text--->"
|
|||
|
|
"<text>_ includes [ _ ]</text--->"
|
|||
|
|
"<text>Returns true, if pos2 is included in pos2</text--->"
|
|||
|
|
"<text>query pos1 includes [pos2]</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int includesValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Position * pos1 = ( ( Position* ) args[ 0 ].addr );
|
|||
|
|
Position * pos2 = ( ( Position* ) args[ 1 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
( ( CcBool* ) result.addr ) ->Set( true, pos2->IsIncluded( pos1 ) );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr includesTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 2 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg1 = nl->First( args );
|
|||
|
|
ListExpr arg2 = nl->Second( args );
|
|||
|
|
if ( ( nl->IsEqual( arg1, "position" ) )
|
|||
|
|
&& ( nl->IsEqual( arg2, "position" ) ) )
|
|||
|
|
return nl->SymbolAtom( "bool" );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.8 Operator getposition
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string getpositionSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>game int -> position</text--->"
|
|||
|
|
"<text>_ getposition [_]</text--->"
|
|||
|
|
"<text>Returns position of a game after the specificated move</text--->"
|
|||
|
|
"<text>query game getposition [4]</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int getpositionValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Chessgame * game = ( ( Chessgame* ) args[ 0 ].addr );
|
|||
|
|
CcInt * moveNumber = ( ( CcInt* ) args[ 1 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
if ( ( moveNumber->GetValue() < 0 )
|
|||
|
|
|| ( moveNumber->GetValue() > game->GetMovesCount() ) )
|
|||
|
|
( ( Position* ) result.addr ) ->SetDefined( false );
|
|||
|
|
else
|
|||
|
|
game->GetPosition( ( Position* ) result.addr, moveNumber->GetValue() );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr getpositionTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 2 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg1 = nl->First( args );
|
|||
|
|
ListExpr arg2 = nl->Second( args );
|
|||
|
|
if ( ( nl->IsEqual( arg1, "chessgame" ) )
|
|||
|
|
&& ( nl->IsAtom( arg2 ) && nl->IsEqual( arg2, "int" ) ) )
|
|||
|
|
return nl->SymbolAtom( "position" );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.8 Operator getmove
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string getmoveSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>game int -> move</text--->"
|
|||
|
|
"<text>_ getmove [_]</text--->"
|
|||
|
|
"<text>Returns specified move of a game</text--->"
|
|||
|
|
"<text>query game getmove [4]</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int getmoveValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Chessgame * game = ( ( Chessgame* ) args[ 0 ].addr );
|
|||
|
|
CcInt * moveNumber = ( ( CcInt* ) args[ 1 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
if ( ( moveNumber->GetValue() < 1 )
|
|||
|
|
|| ( moveNumber->GetValue() > game->GetMovesCount() ) )
|
|||
|
|
( ( Move* ) result.addr ) ->SetDefined( false );
|
|||
|
|
else
|
|||
|
|
game->GetMove( (* ( Move* ) result.addr), moveNumber->GetValue() );
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr getmoveTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 2 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg1 = nl->First( args );
|
|||
|
|
ListExpr arg2 = nl->Second( args );
|
|||
|
|
if ( ( nl->IsEqual( arg1, "chessgame" ) )
|
|||
|
|
&& ( nl->IsAtom( arg2 ) && nl->IsEqual( arg2, "int" ) ) )
|
|||
|
|
return nl->SymbolAtom( "chessmove" );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.9 Operator getkey
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string getkeySpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>game string -> string</text--->"
|
|||
|
|
"<text>_ getkey [_]</text--->"
|
|||
|
|
"<text>Returns specified data of a game</text--->"
|
|||
|
|
"<text>query game getkey [\"name_w\"]</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int getkeyValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Chessgame * game = ( ( Chessgame* ) args[ 0 ].addr );
|
|||
|
|
CcString * key = ( ( CcString* ) args[ 1 ].addr );
|
|||
|
|
result = qp->ResultStorage( s );
|
|||
|
|
STRING_T resultStr;
|
|||
|
|
game->GetMetainfoValue( key->GetValue(), &resultStr );
|
|||
|
|
( ( CcString* ) result.addr ) ->Set( true, &resultStr ) ;
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr getkeyTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 2 )
|
|||
|
|
{
|
|||
|
|
ListExpr arg1 = nl->First( args );
|
|||
|
|
ListExpr arg2 = nl->Second( args );
|
|||
|
|
if ( ( nl->IsEqual( arg1, "chessgame" ) )
|
|||
|
|
&& ( nl->IsAtom( arg2 ) && nl->IsEqual( arg2, "string" ) ) )
|
|||
|
|
return nl->SymbolAtom( "string" );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
struct Localinfo
|
|||
|
|
{
|
|||
|
|
Chessgame * game;
|
|||
|
|
int cntr;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.10 Operator moves
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string movesSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>game -> moves</text--->"
|
|||
|
|
"<text>_ moves</text--->"
|
|||
|
|
"<text>Returns a stream of all moves of a game</text--->"
|
|||
|
|
"<text>query game moves</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int movesValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Localinfo * localinfo = new Localinfo;
|
|||
|
|
switch ( message )
|
|||
|
|
{
|
|||
|
|
case OPEN:
|
|||
|
|
localinfo->game = ( Chessgame* ) args[ 0 ].addr;
|
|||
|
|
localinfo->cntr = 1;
|
|||
|
|
local.addr = localinfo;
|
|||
|
|
return 0;
|
|||
|
|
case REQUEST:
|
|||
|
|
localinfo = ( Localinfo* ) local.addr;
|
|||
|
|
if ( localinfo->cntr <= ( localinfo->game->GetMovesCount() ) )
|
|||
|
|
{
|
|||
|
|
Move m = localinfo->game->GetMove( localinfo->cntr++ );
|
|||
|
|
Move* res = new Move(m);
|
|||
|
|
|
|||
|
|
result.addr = res;
|
|||
|
|
return YIELD;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
return CANCEL;
|
|||
|
|
case CLOSE:
|
|||
|
|
localinfo = ( Localinfo* ) local.addr;
|
|||
|
|
delete localinfo;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ListExpr movesTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 1 )
|
|||
|
|
{
|
|||
|
|
if ( nl->IsEqual( nl->First( args ), "chessgame" ) )
|
|||
|
|
return nl->TwoElemList( nl->SymbolAtom( "stream" ),
|
|||
|
|
nl->SymbolAtom( "chessmove" ) );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.10 Operator positions
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
const string positionsSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>game -> positions</text--->"
|
|||
|
|
"<text>_ moves</text--->"
|
|||
|
|
"<text>Returns a stream of all moves of a game</text--->"
|
|||
|
|
"<text>query game positions</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int positionsValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
Localinfo * localinfo = new Localinfo();
|
|||
|
|
switch ( message )
|
|||
|
|
{
|
|||
|
|
case OPEN:
|
|||
|
|
localinfo->game = ( Chessgame* ) args[ 0 ].addr;
|
|||
|
|
localinfo->cntr = 0;
|
|||
|
|
local.addr = localinfo;
|
|||
|
|
return 0;
|
|||
|
|
case REQUEST:
|
|||
|
|
localinfo = ( Localinfo* ) local.addr;
|
|||
|
|
if ( localinfo->cntr <= ( localinfo->game->GetMovesCount() ) )
|
|||
|
|
{
|
|||
|
|
result.addr = ( localinfo->game->GetPosition( localinfo->cntr++ ) );
|
|||
|
|
return YIELD;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
return CANCEL;
|
|||
|
|
case CLOSE:
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
ListExpr positionsTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
if ( nl->ListLength( args ) == 1 )
|
|||
|
|
{
|
|||
|
|
if ( nl->IsEqual( nl->First( args ), "chessgame" ) )
|
|||
|
|
return nl->TwoElemList( nl->SymbolAtom( "stream" ),
|
|||
|
|
nl->SymbolAtom( "position" ) );
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
3.11 Operator movingpoints
|
|||
|
|
|
|||
|
|
Dieser Fehler ist in der movingpoints-Implementierung enthalten:
|
|||
|
|
|
|||
|
|
Wenn eine Figur geschlagen wird, wandert sie auf die Koordinaten (x,
|
|||
|
|
y+-2), wenn seine Anfangskoordinaten (x,y) waren; dabei gilt "+" f<EFBFBD>r
|
|||
|
|
schwarze und "-" f<EFBFBD>r wei<EFBFBD>e Figuren. Z.B. wandert die wei<EFBFBD>e Dame auf die
|
|||
|
|
Koordinaten (4.0, -1.0).
|
|||
|
|
Handelt es ich bei der geschlagenen Figur um einen Offizier, der aus
|
|||
|
|
einer Bauernumwandlung hervorging, so zeigen seine Anfangskoordinaten
|
|||
|
|
auf die gegnerische Grundlinie. Er zieht also auf die Linie 6, wenn er
|
|||
|
|
wei<EFBFBD> ist, auf die Linie 3, wenn er schwarz ist - und da geh<EFBFBD>rt er nun
|
|||
|
|
wirklich nicht hin.
|
|||
|
|
|
|||
|
|
M<EFBFBD>gliche L<EFBFBD>sungsvarianten w<EFBFBD>ren:
|
|||
|
|
|
|||
|
|
- <EFBFBD>nderung des Figurtyps beim umgewandelten Bauern statt Erzeugung einer
|
|||
|
|
neuen Figur (das hat Vor- und Nachteile f<EFBFBD>r manche analytischen Abfragen)
|
|||
|
|
|
|||
|
|
- Setzen eines Flags "isPromotedPawn" oder so, das bei der Berechnung
|
|||
|
|
des Abstellplatzes ausgewertet wird
|
|||
|
|
|
|||
|
|
- Festlegen des Abstellplatzes bei der Initialisierung, statt sie erst
|
|||
|
|
im Moment des Schlagens zu berechnen
|
|||
|
|
|
|||
|
|
Bei der 2. und 3. L<EFBFBD>sung m<EFBFBD><EFBFBD>te man noch <EFBFBD>berlegen, was ein geeigneter
|
|||
|
|
Abstellplatz ist und wie man zuverl<EFBFBD>ssig vermeidet, da<EFBFBD> dort mehrere
|
|||
|
|
Figuren abgestellt werden.
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
const string movingpointsSpec =
|
|||
|
|
"(" "(" "\"Signature\"" "\"Syntax\"" "\"Meaning\"" "\"Example\"" ")" "("
|
|||
|
|
"<text>chessgame -> stream(tup(Piece White Route)</text--->"
|
|||
|
|
"<text>with Piece: string, White: bool, Route: mpoint</text--->"
|
|||
|
|
"<text>Returns a stream with all pieces' movements</text--->"
|
|||
|
|
"<text>query game movingpoints consume</text--->"
|
|||
|
|
")" ")";
|
|||
|
|
|
|||
|
|
int movingpointsValueMap( Word * args, Word & result,
|
|||
|
|
int message, Word & local, Supplier s )
|
|||
|
|
{
|
|||
|
|
MovingChessPieces * mcps = 0;
|
|||
|
|
MovingChessPiece* mcp = 0;
|
|||
|
|
Chessgame* game = 0;
|
|||
|
|
Move mv;
|
|||
|
|
string startfile, endfile, argstr;
|
|||
|
|
CcString* ki = 0;
|
|||
|
|
STRING_T hilfstr;
|
|||
|
|
CcBool* iw = 0;
|
|||
|
|
MPoint* mp = 0;
|
|||
|
|
int i = 0;
|
|||
|
|
ListExpr resultType;
|
|||
|
|
TupleType* resultTupleType = 0;
|
|||
|
|
Tuple* tup = 0;
|
|||
|
|
switch ( message )
|
|||
|
|
{
|
|||
|
|
case OPEN:
|
|||
|
|
game = ( Chessgame* ) args[ 0 ].addr;
|
|||
|
|
resultType = GetTupleResultType( s );
|
|||
|
|
resultTupleType = new TupleType( nl->Second( resultType ) );
|
|||
|
|
/*
|
|||
|
|
The result is a stream of tuples with an attribute of type mpoint,
|
|||
|
|
these mpoints must be completely created from the chessgame before
|
|||
|
|
the first tuple can be written. Therefore, this work is done when the
|
|||
|
|
stream is opened.
|
|||
|
|
1st step: create the movingpoints for the start position of the game
|
|||
|
|
*/
|
|||
|
|
mcps = new MovingChessPieces();
|
|||
|
|
local.addr = mcps;
|
|||
|
|
mcps->setTupleTypeRemember( resultTupleType );
|
|||
|
|
/*
|
|||
|
|
2nd step: read all moves of the game and realize it in the mcps structure
|
|||
|
|
*/
|
|||
|
|
for ( i = 1;i <= game->GetMovesCount();i++ )
|
|||
|
|
{
|
|||
|
|
Move m1;
|
|||
|
|
game->GetMove(m1,i);
|
|||
|
|
MoveData m2 = game->GetMoveData(i-1);
|
|||
|
|
mcps->realizeMove( &m1, &m2 );
|
|||
|
|
}
|
|||
|
|
mcps->closeMPoints();
|
|||
|
|
|
|||
|
|
return 0;
|
|||
|
|
case REQUEST:
|
|||
|
|
mcps = ( MovingChessPieces* ) local.addr;
|
|||
|
|
// reestablish access to moving points array
|
|||
|
|
i = mcps->getMPointWriteNextCount();
|
|||
|
|
// look how many tuples have been written
|
|||
|
|
if ( i < 48 )
|
|||
|
|
{
|
|||
|
|
while ( i < 48 )
|
|||
|
|
{
|
|||
|
|
if ( mcps->isValid( i ) ) break;
|
|||
|
|
// only write mpoints representing chesspieces used
|
|||
|
|
i++;
|
|||
|
|
mcps->incMPointWriteNextCount();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ( i >= 48 ) return CANCEL;
|
|||
|
|
// if i !< 48: no valid mpoints any more to write
|
|||
|
|
|
|||
|
|
mcps->incMPointWriteNextCount();
|
|||
|
|
mcp = mcps->getMovingChessPiece( i );
|
|||
|
|
resultTupleType = mcps->getTupleTypeRemember();
|
|||
|
|
tup = new Tuple( resultTupleType );
|
|||
|
|
strcpy( hilfstr, ( char* ) ( mcp->getKind() ->c_str() ) );
|
|||
|
|
ki = new CcString( true, &hilfstr );
|
|||
|
|
tup->PutAttribute( 0, ( Attribute* ) ki );
|
|||
|
|
iw = new CcBool( true, *( mcp->trueIsWhite() ) );
|
|||
|
|
tup->PutAttribute( 1, ( Attribute* ) iw );
|
|||
|
|
mp = mcp->getMPoint();
|
|||
|
|
tup->PutAttribute( 2, ( ( Attribute* ) mp ) ->Clone() );
|
|||
|
|
result = SetWord( tup );
|
|||
|
|
return YIELD;
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
return CANCEL;
|
|||
|
|
case CLOSE:
|
|||
|
|
//cout << "movingpointsValueMap entered for CLOSE" << endl;
|
|||
|
|
mcps = ( MovingChessPieces* ) local.addr;
|
|||
|
|
// reestablish access to moving points array
|
|||
|
|
mcps->getTupleTypeRemember() ->DeleteIfAllowed();
|
|||
|
|
delete mcps;
|
|||
|
|
return 0;
|
|||
|
|
}
|
|||
|
|
return -1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
ListExpr movingpointsTypeMap( ListExpr args )
|
|||
|
|
{
|
|||
|
|
ListExpr streamList, tupleList;
|
|||
|
|
string argstr;
|
|||
|
|
|
|||
|
|
nl->WriteToString( argstr, args );
|
|||
|
|
if ( nl->ListLength( args ) == 1 )
|
|||
|
|
{
|
|||
|
|
tupleList = nl->ThreeElemList(
|
|||
|
|
nl->TwoElemList(
|
|||
|
|
nl->SymbolAtom( "Piece" ), nl->SymbolAtom( "string" ) ),
|
|||
|
|
nl->TwoElemList(
|
|||
|
|
nl->SymbolAtom( "White" ), nl->SymbolAtom( "bool" ) ) ,
|
|||
|
|
nl->TwoElemList(
|
|||
|
|
nl->SymbolAtom( "Route" ), nl->SymbolAtom( "mpoint" ) )
|
|||
|
|
);
|
|||
|
|
streamList = nl->TwoElemList( nl->SymbolAtom( "stream" ),
|
|||
|
|
nl->TwoElemList( nl->SymbolAtom( "tuple" ),
|
|||
|
|
tupleList ) );
|
|||
|
|
if ( nl->IsEqual( nl->First( args ), "chessgame" ) )
|
|||
|
|
{
|
|||
|
|
nl->WriteToString( argstr, streamList );
|
|||
|
|
return streamList;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
return nl->SymbolAtom( "typeerror" );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
4 Build Type Constructors
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
TypeConstructor materialTC(
|
|||
|
|
"material",
|
|||
|
|
MaterialProp,
|
|||
|
|
OutMaterial, InMaterial,
|
|||
|
|
0, 0,
|
|||
|
|
CreateMaterial, DeleteMaterial,
|
|||
|
|
0, 0,
|
|||
|
|
CloseMaterial, CloneMaterial,
|
|||
|
|
CastMaterial,
|
|||
|
|
SizeOfMaterial,
|
|||
|
|
MaterialType
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
TypeConstructor moveTC(
|
|||
|
|
"chessmove",
|
|||
|
|
MoveProp,
|
|||
|
|
OutMove, InMove,
|
|||
|
|
0, 0,
|
|||
|
|
CreateMove, DeleteMove,
|
|||
|
|
0, 0,
|
|||
|
|
CloseMove, CloneMove,
|
|||
|
|
CastMove,
|
|||
|
|
SizeOfMove,
|
|||
|
|
MoveType
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
TypeConstructor positionTC(
|
|||
|
|
"position",
|
|||
|
|
PositionProp,
|
|||
|
|
OutPosition, InPosition,
|
|||
|
|
0, 0,
|
|||
|
|
CreatePosition, DeletePosition,
|
|||
|
|
0, 0,
|
|||
|
|
ClosePosition, ClonePosition,
|
|||
|
|
CastPosition,
|
|||
|
|
SizeOfPosition,
|
|||
|
|
PositionType
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
#ifdef RELALG_PERSISTENT
|
|||
|
|
TypeConstructor gameTC(
|
|||
|
|
"chessgame",
|
|||
|
|
ChessgameProp,
|
|||
|
|
OutChessgame, InChessgame,
|
|||
|
|
0, 0,
|
|||
|
|
CreateChessgame, DeleteChessgame,
|
|||
|
|
OpenChessgame, SaveChessgame,
|
|||
|
|
CloseChessgame, CloneChessgame,
|
|||
|
|
CastChessgame,
|
|||
|
|
SizeOfChessgame,
|
|||
|
|
ChessgameType
|
|||
|
|
);
|
|||
|
|
#else
|
|||
|
|
TypeConstructor gameTC(
|
|||
|
|
"chessgame",
|
|||
|
|
ChessgameProp,
|
|||
|
|
OutChessgame, InChessgame,
|
|||
|
|
0, 0,
|
|||
|
|
CreateChessgame, DeleteChessgame,
|
|||
|
|
0, 0,
|
|||
|
|
CloseChessgame, CloneChessgame,
|
|||
|
|
CastChessgame,
|
|||
|
|
SizeOfChessgame,
|
|||
|
|
ChessgameType
|
|||
|
|
);
|
|||
|
|
#endif // RELALG_PERSISTENT
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
5 Build Operators
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
Operator readpgnOp (
|
|||
|
|
"readpgn",
|
|||
|
|
readpgnSpec,
|
|||
|
|
readpgnValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
readpgnTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator agentOp (
|
|||
|
|
"agent",
|
|||
|
|
agentSpec,
|
|||
|
|
agentValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
moveStrTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator capturedOp (
|
|||
|
|
"captured",
|
|||
|
|
capturedSpec,
|
|||
|
|
capturedValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
moveStrTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator startrowOp (
|
|||
|
|
"startrow",
|
|||
|
|
startrowSpec,
|
|||
|
|
startrowValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
moveIntTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator endrowOp (
|
|||
|
|
"endrow",
|
|||
|
|
endrowSpec,
|
|||
|
|
endrowValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
moveIntTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator startfileOp (
|
|||
|
|
"startfile",
|
|||
|
|
startfileSpec,
|
|||
|
|
startfileValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
moveStrTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator endfileOp (
|
|||
|
|
"endfile",
|
|||
|
|
endfileSpec,
|
|||
|
|
endfileValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
moveStrTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator checkOp (
|
|||
|
|
"check",
|
|||
|
|
checkSpec,
|
|||
|
|
checkValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
moveBoolTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator capturesOp (
|
|||
|
|
"captures",
|
|||
|
|
capturesSpec,
|
|||
|
|
capturesValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
moveBoolTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
ValueMapping piececount_vms[] =
|
|||
|
|
{
|
|||
|
|
piececount_vm,
|
|||
|
|
piececount_vm2
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
ValueMapping equal_vms[] =
|
|||
|
|
{
|
|||
|
|
equal_vm<Material>,
|
|||
|
|
equal_vm<Position>
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
ValueMapping approxequal_vms[] =
|
|||
|
|
{
|
|||
|
|
approxequal_vm<Material>,
|
|||
|
|
approxequal_vm<Position>
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
ValueMapping less_vms[] =
|
|||
|
|
{
|
|||
|
|
less_vm<Material>,
|
|||
|
|
less_vm<Position>
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
Operator piecesOp (
|
|||
|
|
"pieces",
|
|||
|
|
piecesSpec,
|
|||
|
|
piecesValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
piecesTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator moveNoOp (
|
|||
|
|
"moveNo",
|
|||
|
|
moveNoSpec,
|
|||
|
|
2, moveNoMap,
|
|||
|
|
moveNoSelect,
|
|||
|
|
moveNoTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator rangeOp (
|
|||
|
|
"posrange",
|
|||
|
|
rangeSpec,
|
|||
|
|
rangeValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
rangeTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator includesOp (
|
|||
|
|
"includes",
|
|||
|
|
includesSpec,
|
|||
|
|
includesValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
includesTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator getpositionOp (
|
|||
|
|
"getposition",
|
|||
|
|
getpositionSpec,
|
|||
|
|
getpositionValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
getpositionTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator getmoveOp (
|
|||
|
|
"getmove",
|
|||
|
|
getmoveSpec,
|
|||
|
|
getmoveValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
getmoveTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator getkeyOp (
|
|||
|
|
"getkey",
|
|||
|
|
getkeySpec,
|
|||
|
|
getkeyValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
getkeyTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator movesOp (
|
|||
|
|
"moves",
|
|||
|
|
movesSpec,
|
|||
|
|
movesValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
movesTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator positionsOp (
|
|||
|
|
"positions",
|
|||
|
|
positionsSpec,
|
|||
|
|
positionsValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
positionsTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
Operator movingpointsOp (
|
|||
|
|
"movingpoints",
|
|||
|
|
movingpointsSpec,
|
|||
|
|
movingpointsValueMap,
|
|||
|
|
Operator::SimpleSelect,
|
|||
|
|
movingpointsTypeMap
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
/*
|
|||
|
|
6 Build Algebra
|
|||
|
|
|
|||
|
|
*/
|
|||
|
|
class ChessAlgebra : public Algebra
|
|||
|
|
{
|
|||
|
|
public:
|
|||
|
|
ChessAlgebra() : Algebra()
|
|||
|
|
{
|
|||
|
|
AddTypeConstructor( &materialTC );
|
|||
|
|
AddTypeConstructor( &moveTC );
|
|||
|
|
AddTypeConstructor( &positionTC );
|
|||
|
|
AddTypeConstructor( &gameTC );
|
|||
|
|
|
|||
|
|
materialTC.AssociateKind( "DATA" );
|
|||
|
|
moveTC.AssociateKind( "DATA" );
|
|||
|
|
positionTC.AssociateKind( "DATA" );
|
|||
|
|
gameTC.AssociateKind( "DATA" );
|
|||
|
|
|
|||
|
|
materialTC.AssociateKind( "INDEXABLE" );
|
|||
|
|
moveTC.AssociateKind( "INDEXABLE" );
|
|||
|
|
positionTC.AssociateKind( "INDEXABLE" );
|
|||
|
|
gameTC.AssociateKind( "INDEXABLE" );
|
|||
|
|
|
|||
|
|
AddOperator( &readpgnOp );
|
|||
|
|
AddOperator( &agentOp );
|
|||
|
|
AddOperator( &capturedOp );
|
|||
|
|
AddOperator( &startrowOp );
|
|||
|
|
AddOperator( &endrowOp );
|
|||
|
|
AddOperator( &startfileOp );
|
|||
|
|
AddOperator( &endfileOp );
|
|||
|
|
AddOperator( &checkOp );
|
|||
|
|
AddOperator( &capturesOp );
|
|||
|
|
AddOperator( piececountInfo(), piececount_vms,
|
|||
|
|
piececount_sf, piececount_tm );
|
|||
|
|
|
|||
|
|
AddOperator( equalInfo(), equal_vms, equal_sf, equal_tm );
|
|||
|
|
AddOperator( approxequalInfo(), approxequal_vms, equal_sf, equal_tm );
|
|||
|
|
AddOperator( lessInfo(), less_vms, equal_sf, equal_tm );
|
|||
|
|
|
|||
|
|
AddOperator( &piecesOp );
|
|||
|
|
AddOperator( &moveNoOp );
|
|||
|
|
AddOperator( &rangeOp );
|
|||
|
|
AddOperator( &includesOp );
|
|||
|
|
AddOperator( &getpositionOp );
|
|||
|
|
AddOperator( &getmoveOp );
|
|||
|
|
AddOperator( &getkeyOp );
|
|||
|
|
AddOperator( &movesOp );
|
|||
|
|
AddOperator( &positionsOp );
|
|||
|
|
AddOperator( &movingpointsOp );
|
|||
|
|
}
|
|||
|
|
~ChessAlgebra() {}
|
|||
|
|
;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
extern "C"
|
|||
|
|
Algebra*
|
|||
|
|
InitializeChessAlgebra( NestedList * nlRef, QueryProcessor * qpRef )
|
|||
|
|
{
|
|||
|
|
nl = nlRef;
|
|||
|
|
qp = qpRef;
|
|||
|
|
return ( new ChessAlgebra() );
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
} // Namespace chessAlgebra
|