Difference between revisions of "Tutorial Project. Release 7"

From wiki.visual-prolog.com

m
m
Line 1: Line 1:
{{spbCopyright}}
This program is part of the [[Tutorial Project Evolutions]] article.
This program is part of the [[Tutorial Project Evolutions]] article.


Line 27: Line 29:
/***************************************************************
/***************************************************************
VIP 7.2
VIP 7.2
Copyright (c) 2007-2008 Prolog Development Center SPb
Copyright (c) 2007-2008 Victor Yukhtenko


SpbSolutions/Examples/Polyline
SpbSolutions/Examples/Polyline

Revision as of 15:45, 26 May 2010

Written by Victor Yukhtenko. Email: victor@pdc.spb.su

This program is part of the Tutorial Project Evolutions article.

Tutorial Project. Release 7


Game description

The game is played on an M x N board.

Game rules

  • Each player on his turn adds a new point. The point must prolong the existing Polyline (or start the Polyline, if it doesn't exist).
  • The resulting Polyline must be non-interrupted and each move can be taken in any of end of the line.
  • The player, which locks the line (the point is set on the polyline), wins.

Differences (relative to version 6):

  • Multilanguage feature
  • Indication of the process in the multi game mode
  • Code rerganized

This page doesn't contain models of players.

To run the game please make the steps as follows:

  • Create the new project with the User Interface strategy Console
  • In the created project replace the entire content of the file "main.pro" by the code shown below (VIP 7.2 only)
  • Add to the file "main.pro" the text of the program at the page Class GenericComputer
  • Add to the file "main.pro" classes of players
  • While building the project answer "Add All", when any dialog with proposals to include any packages to the project appears

The language of the application may be defined in the command line by the language indetifier:

  • en - English
  • ru - Russian

When running the program from the IDE, the parameter of the language must be placed to the field "Project Settings"\Run Options\Run Arguments, available from menu Project\Settings...

/***************************************************************
VIP 7.2
Copyright (c) 2007-2008 Victor Yukhtenko
 
SpbSolutions/Examples/Polyline
 
Predicates
    neighbour_nd,
    neighbourOutOfPolyLine_nd
based on solutions proposed by Elena Efimova
 
Written by: Victor Yukhtenko
***************************************************************/
 
/*****************
  GOAL
*****************/
goal
    mainExe::run(main::run).
 
/*****************
  Class Main
*****************/
implement main
    open core
 
constants
    className = "main".
    classVersion = "1.0".
 
clauses
    classInfo(className, classVersion).
 
clauses
    run():-
        console::init(),   
        game::run().
 
end implement main
 
class game
open core
 
predicates
    classInfo : core::classInfo.
 
domains
    language_D=
        en;
        ru.
 
properties
    language_V:language_D.
    players_V:player*.
    multiMode_V:boolean.
 
predicates
    run:().
    addPlayer:(player Player).
 
end class game
 
implement game
open core
 
constants
    className = "game".
    classVersion = "1.0".
 
clauses
    classInfo(className, classVersion).
 
class facts
    language_V:language_D:=en.
    multiMode_V:boolean:=false.
 
clauses
    run():-
        setLanguage(),
        humanInterface::setLanguage(language_V),
        Mode=chooseSingleOrMultiGame(),
        setGameProperties(),
        competitors::involvePlayers(),
        if Mode=single_S then 
            playSingle()
        else
            multiMode_V:=true,
            seniourJudge::playMulti()
        end if.
 
domains
    mode_D=
        single_S;
        multi_S.
 
class predicates
    setLanguage:().
clauses
    setLanguage():-
        CommandLine = exe_native::getCommandLine(),
        if string::hasSuffix(CommandLine,"ru",_RestRu) then
            language_V:=ru
        end if,
        if string::hasSuffix(CommandLine,"en",_RestEn) then
            language_V:=en
        end if.
 
class predicates
    chooseSingleOrMultiGame:()->mode_D GameOrCompetition.
clauses
    chooseSingleOrMultiGame()=Choice:-
        ChoiceStr=humanInterface::getInput(humanInterface::singleOrMulti_S),
        if (string::equalIgnoreCase(ChoiceStr,"S") or ChoiceStr=""),! then
            Choice=single_S,
            !
        else
            Choice=multi_S
        end if.
 
class predicates
    playSingle:().
clauses
    playSingle():-
        StartingPlayer=chooseStartingPlayer(),
        seniourJudge::playSingle(StartingPlayer),
        !,
        playSingle().
    playSingle().
 
class predicates
    setGameProperties:().
clauses
    setGameProperties():-
        juniourJudge::defineStage().
 
/***************************
  Players
***************************/
class facts
    players_V:player*:=[].
 
clauses
    addPlayer(Player):-
        players_V:=list::append(players_V,[Player]).
 
/***************************
 Shoose Starting Player
***************************/
class predicates
    chooseStartingPlayer:()->player determ.
clauses
    chooseStartingPlayer()=Player:-
        not(players_V=[]) and not(players_V=[_SiglePlayer]),
        findAll(PlayListMember,PlayListMember=playListMember(),PlayList),
        PlayListStr=string::concatList(PlayList),
        StartingPlayer=getStartingPlayerInput(PlayListStr),
        Player=list::nth(StartingPlayer-1,players_V).
 
class predicates
    playListMember:()->string nondeterm.
clauses
    playListMember()=PlayersListMember:-
        I = std::fromTo(1, list::length(game::players_V)),
            Player=list::nth(I-1,game::players_V),
            PlayersListMember=string::format("\n% - %",I,Player:name).
 
class predicates
    getStartingPlayerInput:(string PlayListStr)->positive StartingPlayerNo determ.
clauses
    getStartingPlayerInput(PlayListStr)=StartingPlayer:-
        StartingPlayerStr=humanInterface::getInput(humanInterface::startingPlayer_S,PlayListStr),
        if StartingPlayerStr="" then
            !,
            fail
        else
            try
                StartingPlayer=toTerm(StartingPlayerStr),
                !
            catch _TraceID1 do
                humanInterface::announce(humanInterface::errorMustBeNumber_S,""),
                fail
            end try,
            if StartingPlayer>list::length(players_V) then
                humanInterface::announce(humanInterface::errorStartingPlayer_S,""),
                fail
            end if
        end if.
    getStartingPlayerInput(PlayListStr)=StartingPlayer:-
        StartingPlayer=getStartingPlayerInput(PlayListStr).
 
end implement game
 
/************************
  Class seniorJudge
************************/
class seniourJudge
open core
 
properties
    inProgress_V:boolean.
 
predicates
    playSingle:(player CurrentPlayer).
    playMulti:().
 
end class seniourJudge
 
implement seniourJudge
open core, humanInterface
 
class facts
    inProgress_V:boolean:=false.
 
clauses
    playSingle(Player):-
        inProgress_V=false,
        humanInterface::showStage(),
        humanInterface::announce(humanInterface::starter_S,Player:name),
        inProgress_V:=true,
        Player:move(),
        playSingle(Player),
        !.
    playSingle(Player):-
        juniourJudge::isGameOver(),
        !,
        if game::multiMode_V=false then
            Player:announceWin(),
            foreach (Participant=list::getMember_nd(game::players_V) and not(Participant=Player)) do
                Participant:announceLoss()
            end foreach
        else
            addWinner(Player)
        end if,
        inProgress_V:=false,
        juniourJudge::reset().
    playSingle(Player):-
        NextPlayer=nextPlayer(Player),
        NextPlayer:move(),
        !,
        playSingle(NextPlayer).
 
class predicates
    nextPlayer:(player CurrentPlayer)->player NextPlayer.
clauses
    nextPlayer(Player)=NextPlayer:-
        Index=list::tryGetIndex(Player,game::players_V),
        NextPlayer=list::tryGetNth(Index+1,game::players_V),
        !.
    nextPlayer(_Player)=list::nth(0,game::players_V).
 
/************************
  Multi Mode Handle
************************/
class predicates
    defineNoOfRounds:().
clauses
    defineNoOfRounds():-
        InputString=humanInterface::getInput(humanInterface::noOfRounds_S,toString(noOfRounds_V)),
        not(InputString=""),
        try
            noOfRounds_V:=toTerm(InputString)
        catch _TraceID do
            humanInterface::announce(humanInterface::errorNoOfRounds_S,""),
            defineNoOfRounds()
        end try,
        !.
    defineNoOfRounds().
 
class facts
    starter_V:player:=erroneous.
    noOfRounds_V:positive:=10.
    statistics_F:(boolean TrueIfWon,player,positive Won).
 
clauses
    playMulti():-
        defineNoOfRounds(),
        Player=list::getMember_nd(game::players_V),
            starter_V:=Player,
            playRound(noOfRounds_V),
        fail().
    playMulti():-
        humanInterface::reset(),
        PlayersNo=list::length(game::players_V),
        humanInterface::announce(humanInterface::reportHeader_S,toString(PlayersNo*noOfRounds_V)),
        findAll
            (
            PlayerResultList,
            (
                Player=list::getMember_nd(game::players_V),
                    WinsFirst=calculateWins(Player,true),
                    WinsNext=calculateWins(Player,false),
                    WnsTotal=WinsFirst+WinsNext,
                    PlayerResultList=[Player:name,toString(WnsTotal),toString(WinsFirst),toString(WinsNext)]
            ),
            PlayerResultListList
            ),
        humanInterface::announce(humanInterface::report_S,toString(PlayerResultListList)),
        fail().
    playMulti():-
        humanInterface::waitOK().
 
class facts
    wins_V:integer:=0.
class predicates
    calculateWins:(player Player,boolean TrueIfFirst)->integer Sum.
clauses
    calculateWins(Player,TrueIfFirst)=_:-
        wins_V:=0,
        statistics_F(TrueIfFirst,Player,Won),
            trap(wins_V:=wins_V+Won,_TraceID,fail),
        fail.
    calculateWins(_Player,_TrueIfFirst)=wins_V.
 
class predicates
    playRound:(positive NoOfRounds).
clauses
    playRound(0):-!.
    playRound(NoOfRounds):-
        humanInterface::announce(round_S,toString(noOfRounds_V-NoOfRounds+1)),
        seniourJudge::playSingle(starter_V),
        playRound(NoOfRounds-1).
 
class predicates
    addWinner:(player).
clauses
    addWinner(Player):-
        if Player=starter_V then 
            TrueIfStarted=true 
        else
            TrueIfStarted=false 
        end if,
        addWinner(TrueIfStarted,Player).
 
class predicates
    addWinner:(boolean TrueIfStarted,player Player).
clauses
    addWinner(TrueIfStarted,Player):-
        retract(statistics_F(TrueIfStarted,Player,Won)),
        !,
        assert(statistics_F(TrueIfStarted,Player,Won+1)).
    addWinner(TrueIfStarted,Player):-
        assert(statistics_F(TrueIfStarted,Player,1)).
 
end implement seniourJudge
 
/************************
  Class juniourJudge
************************/
class juniourJudge
open core
 
predicates
    classInfo : core::classInfo.
 
domains
    cell = c(positive,positive).
    stepType_D=
        ordinary_S;
        winner_S.
 
properties
    maxRow_P:positive.
    maxColumn_P:positive.
    polyline_P:cell*.
 
predicates
    defineStage:().
    neighbour_nd: (cell,cell) nondeterm (i,o) (i,i).
    neighbourOutOfPolyLine_nd:(cell,cell)->cell nondeterm.
    set: (string ).
    isGameOver:() determ.
    reset:().
 
end class juniourJudge
 
implement juniourJudge
open core, humanInterface
 
constants
    className = "JuniourJudge".
    classVersion = "1.0".
 
clauses
    classInfo(className, classVersion).
 
class facts
    maxRow_P:positive:=6.
    maxColumn_P:positive:=6.
    polyline_P:cell*:=[].
    endOfGame_V:boolean:=false.
 
domains
    fieldSize_D=tableSize(positive X,positive Y).
 
clauses
    defineStage():-
        defineFieldSize().
 
class predicates
    defineFieldSize:().
clauses
    defineFieldSize():-
        InputString=humanInterface::getInput(humanInterface::fieldSize_S,string::format("%s,%s",toString(maxColumn_P),toString(maxRow_P))),
        not(InputString=""),
        try
            hasDomain(fieldSize_D,FieldSize),
            FieldSize=toTerm(string::format("tableSize(%s)",InputString)),
            FieldSize=tableSize(X,Y),
            maxColumn_P:=X,
            maxRow_P:=Y
        catch _TraceID do
            humanInterface::announce(humanInterface::errorFieldSize_S,""),
            defineFieldSize()
        end try,
        !.
    defineFieldSize().
 
clauses
    isGameOver():-
        endOfGame_V=true.
 
clauses
    set(InputString):-
        Cell=convertToCell(InputString),
        handleInput (Cell).
 
class predicates
    convertToCell:(string InputString)->cell.
clauses
    convertToCell(InputString)=Cell:-
        trap(Cell=toTerm(InputString),_TraceID,fail),
        !.
    convertToCell(InputString)=Cell:-
        CellString=string::format("c(%s)",InputString),
        trap(Cell=toTerm(CellString),_TraceID,fail),
        !.
    convertToCell(InputString)=toTerm(InputString).
 
clauses
    reset():-
        juniourJudge:: polyline_P:=[],
        juniourJudge::endOfGame_V:=false.
 
class predicates
    handleInput:(juniourJudge::cell).
clauses
    handleInput(Cell):-
        list::isMember(Cell,polyline_P),
        try 
            _=makePolyLine(Cell,polyline_P) % it will be an exception if wrong Cell, but we ignore it by failing
        catch _TraceID do
            fail
        end try,
        !,
        endOfGame_V:=true,
        humanInterface::showStep(Cell,winner_S).
    handleInput (Cell):-
        polyline_P:=makePolyLine(Cell,polyline_P),
        !,
        humanInterface::showStep(Cell,ordinary_S).
 
class predicates
    makePolyLine: (cell,cell*)-> cell* multi.
clauses
    makePolyLine(c(X,Y),[])=[c(X,Y)]:-
        X>0,X<=maxColumn_P,
        Y>0,Y<=maxRow_P,
        !.
    makePolyLine(NewCell,[SingleCell])=[NewCell,SingleCell]:-
        neighbour_nd(SingleCell, NewCell),
        !.
    makePolyLine(NewCell,[Left, RestrictingCell | PolyLineTail])=[NewCell, Left, RestrictingCell | PolyLineTail]:-
        NewCell=neighbourOutOfPolyLine_nd(Left,RestrictingCell).
    makePolyLine(NewCell,PolyLine)=list::reverse([NewCell,Left, RestrictingCell | PolyLineTail]):-
        [Left, RestrictingCell | PolyLineTail]= list::reverse(PolyLine),
        NewCell=neighbourOutOfPolyLine_nd(Left,RestrictingCell).
    makePolyLine(NewCell,_PolyLine)= _PolyLine1:-
        exception::raise(classInfo,wrongStepException,[namedValue("data",string(toString(NewCell)))]).
 
class predicates
    wrongStepException:exception.
clauses
    wrongStepException
        (
        classInfo,
        predicate_Name(),
        ""
        ).
 
clauses
    neighbourOutOfPolyLine_nd(Cell,RestrictingCell)=NewCell:-
        neighbour_nd(Cell,NewCell),
            not(NewCell = RestrictingCell).
 
clauses
    neighbour_nd(c(X, Y), c(X + 1, Y)):- X < maxColumn_P.        
    neighbour_nd(c(X, Y), c(X, Y + 1)):- Y < maxrow_P.            
    neighbour_nd(c(X, Y), c(X - 1, Y)):- X > 1.
    neighbour_nd(c(X, Y), c(X, Y - 1)):- Y > 1.    
 
end implement juniourJudge
 
/******************************************
  Interface Player
******************************************/
interface player
 
predicates
    setName:(string).
    move:().
    announceWin:().
    announceLoss:().
 
properties
    name:string.
 
end interface player
 
/**************
  Text localization
**************/
interface polyLineText
open core
 
predicates
        getText:(humanInterface::actionID_D)->string Text.
end interface polyLineText
 
class polyLineTextRu:polyLineText
end class polyLineTextRu
 
implement polyLineTextRu
open core, humanInterface
 
clauses
    getText(TextID)=Text:-
        Text=getTextInt(TextID),
        !.
    getText(_TextID)="Текст не предусмотрен".
 
class predicates
    getTextInt:(humanInterface::actionID_D TextID)->string Text determ.
clauses
    getTextInt(thinker_S)="% думает ...".
    getTextInt(round_S)="Раунд: %".
    getTextInt(beginner_S)="Первый ход: %".
    getTextInt(congratulation_S)="Игрок % выиграл!".
    getTextInt(sorryLoss_S)="%,  к сожалению, Вы проиграли :-(".
 
    getTextInt(singleOrMultipleChoice_S)="Выберите режим (S или Enter - одиночная игра, другое - мульти):".
    getTextInt(fieldSize_S)="\nВведите размер игрового поля X,Y (по умолчанию %):".
    getTextInt(playerStep_S)="Введите координаты клетки как c(X,Y) или как X,Y: ".
    getTextInt(playerType_S)="\nВозможные типы игроков:\n%s\nИгрок #%s. Укажите тип (Enter - конец выбора игроков):".
    getTextInt(playerName_S)="\nВведите имя Игрока (предлагается %):".
    getTextInt(startingPlayer_S)="\nКто первый ходит (номер Игрока или Enter - конец игры)?:".
    getTextInt(searchDepth_S)="\nУкажите глубину поиска решения в шагах(% - по умолчанию): ".
    getTextInt(noOfRounds_S)="\nВведите число партий игры (по умолчанию %):".
    getTextInt(reportHeader_S)="\nРезультаты % игр:".
    getTextInt(playerReport_S)="\nИгрок %:\n\t Всего побед % из них:\n\t\tПри ходе первым - \t%\n\t\tПри ходе следующим - \t% ".
 
    getTextInt(error_S)="Ошибка, % ".
    getTextInt(errorPlayerType_S)="\nТакого ТИПА Игрока нет! Enter - для повторного ввода:".
    getTextInt(errorMustBeNumber_S)="\nДолжен быть номер! Повторите ввод:".
    getTextInt(errorstartingPlayer_S)="\nТакого Игрока нет! Повторите ввод:".
    getTextInt(errorFieldSize_S)="\nНеправильно указан размер игрового поля! Повторите ввод:".
    getTextInt(errorNoOfRounds_S)="\nНеправильно указано число партий! Повторите ввод:".
    getTextInt(errorWrongCell_S)="Ход % не может быть продолжением линии:".
 
end implement polyLineTextRu
 
class polyLineTextEn:polyLineText
end class polyLineTextEn
 
implement polyLineTextEn
open core, humanInterface
 
clauses
    getText(TextID)=Text:-
        Text=getTextInt(TextID),
        !.
    getText(_TextID)="No Text Exists".
 
class predicates
    getTextInt:(humanInterface::actionID_D TextID)->string Text determ.
clauses
    getTextInt(thinker_S)="% is thinking ...".
    getTextInt(round_S)="Round: %".
    getTextInt(beginner_S)="First move done by: %".
    getTextInt(congratulation_S)="Player % won!".
    getTextInt(sorryLoss_S)="%,  Sorry, you loss :-(".
 
    getTextInt(singleOrMultipleChoice_S)="Please choose the mode (S or Enter - single game, other - multiple):".
    getTextInt(fieldSize_S)="\nPlease enter the size of the gaimbling field X,Y (% by default):".
    getTextInt(playerStep_S)="Please enter your move as c(X,Y) or as X,Y: ".
    getTextInt(playerType_S)="\nPossible player types:\n%s\nPlayer #%s. Please enter the player type (Enter - end of list):".
    getTextInt(playerName_S)="\nPlease assign the name to the player (% proposed):".
    getTextInt(startingPlayer_S)="\nWho moves the first (PlayerNo or Enter - end of the game)?:".
    getTextInt(searchDepth_S)="\nChoose the depth of the prognosis (% - by default): ".
    getTextInt(noOfRounds_S)="\nPlease enter the number of games (% by default):".
    getTextInt(reportHeader_S)="\nResult of % games:".
    getTextInt(playerReport_S)="\nPlayer %:\n\t Wins Total % and:\n\t\tWhile first move - \t%\n\t\tWhile next move - \t% ".
 
    getTextInt(error_S)="Error, % ".
    getTextInt(errorPlayerType_S)="\nNo such player type exiasts! Enter - repeat input:".
    getTextInt(errorMustBeNumber_S)="\nMust be number! Please repeat input:".
    getTextInt(errorstartingPlayer_S)="\nNo such Player exiasts! Please repeat input:".
    getTextInt(errorFieldSize_S)="\nWrong size of the field entered! Please repeat input:".
    getTextInt(errorNoOfRounds_S)="\nWrong amount of games entered! Please repeat input:".
    getTextInt(errorWrongCell_S)="The Move % doesn't prolong the PolyLine:".
 
end implement polyLineTextEn
 
/******************************************
  Class HumanInterface
******************************************/
class humanInterface
open core
 
predicates
    classInfo : core::classInfo.
 
domains
    actionID_D=
        beginner_S;
        thinker_S;
        congratulation_S;
        sorryLoss_S;
 
        reportHeader_S;
        playerReport_S;
        report_S;
 
        round_S;
        starter_S;
 
        win_S;
        loss_S;
 
        singleOrMultipleChoice_S;
        fieldSize_S;
        playerStep_S;
        playerType_S;
        playerName_S;
        startingPlayer_S;
        searchDepth_S;
        noOfRounds_S;
 
        singleOrMulti_S;
 
        error_S;
        errorPlayerType_S;
        errorMustBeNumber_S;
        errorstartingPlayer_S;
        errorFieldSize_S;
        errorNoOfRounds_S;
        errorWrongCell_S.
 
predicates
   reset:().
 
predicates
    announceStartUp:().
 
predicates
    setLanguage:(game::language_D).
    waitOK:().
    showStage:().
    showStep:(juniourJudge::cell,juniourJudge::stepType_D).
    getInput:(actionID_D,string StringParameter)->string InputString.
    getInput:(actionID_D)->string InputString.
    announce:(actionID_D AnnounceID,string AnnounceText).
 
end class humanInterface
 
implement humanInterface
open core
 
constants
    className = "humanInterface".
    classVersion = "1.0".
 
clauses
    classInfo(className, classVersion).
 
constants
    cellMarkedOrdinary_C="*".
    cellMarkedWinner_C="O".
 
constants
    verticalSpace_C=2.
    horizontalSpace_C=3.
    emptyLineLenght_C=80.
 
constants % Position of Line
    starterLine_C=1.
    announceLine_C=starterLine_C+1.
    actionLine_C=announceLine_C+1.
    polylineLine_C=actionLine_C+1.
 
class facts
    language_V:polyLineText:=erroneous.
 
clauses
    setLanguage(Language):-
        if Language=game::en then
            language_V:=polyLineTextEn::new()
        else 
            language_V:=polyLineTextRu::new()
        end if.
 
clauses
    getInput(InputType)=Input:-
        Input=getInput(InputType,"").
 
    getInput(InputType,StringParameter)=Input:-
        inputInvitation(InputType,StringParameter),
        !,
        Input = console::readLine(),
        console::clearInput().
    getInput(_InputType,_StringParameter)=_Input:-
        common_Exception::raise_error(classInfo,predicate_Name(),"InternalException. Extra alternative").
 
class predicates
    inputInvitation:(actionID_D,string StringParameter) determ.
clauses
    inputInvitation(playerStep_S,_StringParameter):-
        clearMessageArea(actionLine_C),
        writeMessage(actionLine_C,"%",language_V:getText(playerStep_S)).
    inputInvitation(playerName_S,StringParameter):-
        console::writef(language_V:getText(playerName_S),StringParameter).
    inputInvitation(playerType_S,StringParameter):-
        hasDomain(string,PlayersDescriptor),
        [PlayersDescriptor,PlayerNo]=toTerm(StringParameter),
        console::writef(language_V:getText(playerType_S),PlayersDescriptor,PlayerNo).
    inputInvitation(startingPlayer_S,StringParameter):-
        console::write(StringParameter,language_V:getText(startingPlayer_S)).
    inputInvitation(searchDepth_S,StringParameter):-
        console::writef(language_V:getText(searchDepth_S),StringParameter).
    inputInvitation(fieldSize_S,StringParameter):-
        console::writef(language_V:getText(fieldSize_S),StringParameter).
    inputInvitation(noOfRounds_S,StringParameter):-
        console::writef(language_V:getText(noOfRounds_S),StringParameter).
    inputInvitation(singleOrMulti_S,_StringParameter):-
        console::write(language_V:getText(singleOrMultipleChoice_S)).
 
clauses
    showStage():-
        game::multiMode_V=true,
        !.
    showStage():-
        console::clearOutput(),
        foreach I = std::fromTo(1, juniourJudge::maxColumn_P) do
            console::setLocation(console_native::coord(horizontalSpace_C*I, 0)), 
            console::write(I)
        end foreach,
        foreach J = std::fromTo(1, juniourJudge::maxRow_P) do    
            console::setLocation(console_native::coord(0, verticalSpace_C*J)), 
            console::write(J)
        end foreach.
 
clauses
    showStep(_Cell,_Type):-
        game::multiMode_V=true,
        clearMessageArea(actionLine_C),
        nextChar(char_V),
        !,
        writeMessage(actionLine_C,"%",char_V).
    showStep(juniourJudge::c(X,Y),_Type):-
        console::setLocation(console_native::coord(horizontalSpace_C*X, verticalSpace_C*Y)),
        fail.
    showStep(_Cell,juniourJudge::ordinary_S):-
        console::write(cellMarkedOrdinary_C).
    showStep(_Cell,juniourJudge::winner_S):-
        console::write(cellMarkedWinner_C).
 
class facts
    char_V:string:="-". % -\|/
class predicates
    nextChar:(string CharIn) determ.
clauses
    nextChar("-"):-char_V:="\\".
    nextChar("\\"):-char_V:="|".
    nextChar("|"):-char_V:="/".
    nextChar("/"):-char_V:="-".
 
clauses
    announceStartUp():-
        reset().
 
clauses
    announce(reportHeader_S,Parameter):-
        !,
        console::writef(language_V:getText(reportHeader_S),Parameter).
    announce(report_S,PlayerResultListList):-
        !,
        findAll
            (
            PlayerReport,
            (
            hasDomain(string,Name),
            [Name,WinsTotal,WinsFirst,WinsNext]=list::getMember_nd(toTerm(PlayerResultListList)),
                PlayerReport=string::format(language_V:getText(playerReport_S),Name,WinsTotal,WinsFirst,WinsNext)
             ),   
            PlayerReportList
            ),
        console::write(string::concatList(PlayerReportList)).
    announce(round_S,RoundString):-
        !,
        clearMessageArea(announceLine_C),
        writeMessage(announceLine_C,language_V:getText(round_S),RoundString).
    announce(starter_S,Name):-
        !,
        clearMessageArea(starterLine_C),
        writeMessage(starterLine_C,language_V:getText(beginner_S),Name).
    announce(errorPlayerType_S,_IgnoredText):-
        !,
        console::write(language_V:getText(errorPlayerType_S)),
        _=console::readLine().
    announce(errorMustBeNumber_S,_IgnoredText):-
        !,
        console::write(language_V:getText(errorMustBeNumber_S)).
    announce(errorStartingPlayer_S,_IgnoredText):-
        !,
        console::write(language_V:getText(errorStartingPlayer_S)).
    announce(errorFieldSize_S,_IgnoredText):-
        !,
        console::write(language_V:getText(errorFieldSize_S)).
    announce(errorNoOfRounds_S,_IgnoredText):-
        !,
        console::write(language_V:getText(errorNoOfRounds_S)).
    announce(error_S,ErrorText):-
        !,
        clearMessageArea(announceLine_C),
        writeMessage(announceLine_C,language_V:getText(error_S),ErrorText).
    announce(errorWrongCell_S,InvalidData):-
        !,
        clearMessageArea(announceLine_C),
        writeMessage(announceLine_C,language_V:getText(errorWrongCell_S),InvalidData).
    announce(win_S,Name):-
        !,
        clearMessageArea(announceLine_C),
        clearMessageArea(actionLine_C),
        writeMessage(announceLine_C,language_V:getText(congratulation_S),Name),
        _ = console::readLine().
    announce(loss_S,Name):-
        !,
        clearMessageArea(announceLine_C),
        clearMessageArea(actionLine_C),
        writeMessage(announceLine_C,language_V:getText(sorryLoss_S),Name),
        _ = console::readLine().
    announce(thinker_S,_Name):-
        game::multiMode_V=true,
        !.
    announce(thinker_S,Name):-
        !,
        clearMessageArea(announceLine_C),
        clearMessageArea(actionLine_C),
        writeMessage(actionLine_C,language_V:getText(thinker_S),Name).
    announce(_Any,_Name):-
        common_Exception::raise_error(classInfo,predicate_Name(),"InternalException. Extra alternative").
 
clauses
    waitOK():-
        _=console::readLine().
 
clauses
    reset():-
        console::setLocation(console_native::coord(0,0)),
        console::write(string::create(1600," ")),
        console::clearOutput().
 
class predicates
    clearMessageArea:(positive AreaID).
clauses
    clearMessageArea(AreaID):-
        console::setLocation(console_native::coord(0,juniourJudge::maxRow_P*verticalSpace_C+AreaID)),
        console::write(string::create(emptyLineLenght_C," ")).
 
class predicates
    writeMessage:(positive AreaID,string FormatString,string ParameterString).
clauses
    writeMessage(AreaID,FormatString,ParameterString):-
        console::setLocation(console_native::coord(0, juniourJudge::maxRow_P*verticalSpace_C+AreaID)),
        console::writef(FormatString,ParameterString).
 
end implement humanInterface
 
/******************
  Class Competitors
******************/
class competitors
open core
 
predicates
    involvePlayers:().
 
end class competitors
 
implement competitors
open core
clauses
    involvePlayers():-
        involvePlayers(1).
 
class predicates
    involvePlayers:(positive PlayerNo).
clauses
    involvePlayers(PlayerNo):-
        humanInterface::announceStartUp(),
        findAll
            (
            PlayerDescriptor,
            (
                playerDescriptor(No,PlayerDescriptorSrc),
                PlayerDescriptor=string::format("% - %\n",No,PlayerDescriptorSrc)
            ),
            PlayerDescriptorList
            ),
        PlayersDescriptor=string::concatList(PlayerDescriptorList),
        PlayerType=humanInterface::getInput(humanInterface::playerType_S,toString([PlayersDescriptor,toString(PlayerNo)])),
        not(PlayerType=""),
        try
            Player=createPlayerObject(toTerm(PlayerType)),
            Player:setName(toString(PlayerNo)),
            game::addPlayer(Player),
            NewPlayerNo=PlayerNo+1
        catch _TraceID do
            humanInterface::announce(humanInterface::errorPlayerType_S,""),
            NewPlayerNo=PlayerNo
        end try,
        !,
        involvePlayers(NewPlayerNo).
    involvePlayers(_PlayerNo).
 
 
class predicates
    wrongInputException:exception.
clauses
    wrongInputException
        (
        classInfo,
        predicate_Name(),
        ""
        ).
 
class predicates
    playerDescriptor:(positive No [out],string PlayerDescriptorSrc [out]) multi.
clauses
    playerDescriptor(1,human::getPlayerDescriptor(game::language_V)).
    playerDescriptor(2,computer0::getPlayerDescriptor(game::language_V)).
    playerDescriptor(3,computer1::getPlayerDescriptor(game::language_V)).
    playerDescriptor(4,computer2::getPlayerDescriptor(game::language_V)).
/*Include here lines corresponding to the Player Class*/
%    playerDescriptor(5,computer3::getPlayerDescriptor(game::language_V)).
 
class predicates
    createPlayerObject:(positive)->player.
clauses
    createPlayerObject(1)=Player:-
        !,
        Player=human::new().
   createPlayerObject(2)=Player:-
        !,
        Player=computer0::new().
   createPlayerObject(3)=Player:-
        !,
        Player=computer1::new().
    createPlayerObject(4)=Player:-
        !,
        Player=computer2::new().
/*Include here lines corresponding to the Player Class*/
/*
    createPlayerObject(5)=Player:-
        !,
        Player=computer3::new().
*/
    createPlayerObject(_)=_Player:-
        exception::raise(classInfo,wrongInputException,[]).
 
end implement competitors

References