Учебный Проект. Релиз 7: различия между версиями

Материал из wikiru.visual-prolog.com

м
м
Строка 1: Строка 1:
{{Учебный Проект. Релиз 7}}
{{Учебный Проект. Релиз 7}}
{{PolylineTemplateRu
|goal=
Демонстрация свойств языка Visual Prolog и простейших приемов программирования.
|goalContent=
|code=
* Код реорганизован для поддержки новых функций.
|functionality=
* Механизм мультиязычности;
* Индикация динамики процесса.
|install={{PolylineInstall}}


{{copyright}}
|open=
{{Polyline1_10Open|project='''Examples\Polyline\Polyline1\Polyline7.prj'''}}


Очередная версия Учебного проекта, функциональной идеей которого является простая игра.
{{Polyline1-06Copy_Paste}}


[[Игра "Ползунок". Правила игры|Правила игры ...]]
Если у Вас нет полного набора примеров из VipSpbSDK, то для помещения игры в проект необходимо:
 
*Создать проект с пользовательским интерфейсом типа Console
==Цель==
*В построенном проекте заменить полностью код файла "main.pro" кодом, предложенным ниже
Демонстрация приемов программирования на языке Visual Prolog
*Построить проект
 
==Особенности==
* Механизм мультиязычности
* Индикация динамики процесса
 
==Установка==
'''Внимание: '''Код данной страницы не содержит модели игроков.
*Создать проект с пользовательским интерфейсом типа console
*В построенном проекте заменить полностью код файла "main.pro" кодом, предложенным ниже ('''только VIP 7.2''')
*Добавить в файл "main.pro" текст программы страницы ''Класс GenericComputer''
*Добавить в файл "main.pro" текст программы страницы ''Класс GenericComputer''
*Добавить в файл "main.pro" классы игроков с одновременной модификацией класса '''competitiors'''  
*Добавить в файл "main.pro" классы игроков с одновременной модификацией класса '''competitors'''
*При построении проекта ответить на предложение о включении дополнительных пакетов в проект "Add All".
|run=Запуск приложения из среды по '''E''' или запустить исполняемое приложение из директории EXE.
 
==Запуск==
*Язык приложения определяется помещением в командной строке идентификатора языка:
**ru - русский
**en - английский
*При запуске из среды IDE параметр языка помещается в поле формы '''"Project Settings"\Run Options\Run Arguments''', получаемой из меню '''Project\Settings...'''
 
<vip>
<vip>
/***************************************************************
/****************************************************
Copyright (c) 2007-2008 Prolog Development Center SPb
Copyright (c) Victor Yukhtenko


SpbSolutions/Examples/Polyline
SpbSolutions/Examples/Polyline
 
Predicates
Predicates, which represent the strategy
     neighbour_nd,
     neighbour_nd,
     neighbourOutOfPolyLine_nd
     neighbourOutOfPolyLine_nd,
    stepCandidate
based on solutions proposed by Elena Efimova
based on solutions proposed by Elena Efimova
 
Predidcates
Written by: Victor Yukhtenko
    successfulStep
***************************************************************/
modified
 
*****************************************************/
/*****************
/*****************
   GOAL
   GOAL
Строка 48: Строка 44:
     mainExe::run(main::run).
     mainExe::run(main::run).
   
   
/*****************
/**************
  Class Main
Class Main
*****************/
**************/
implement main
implement main
     open core
     open core
Строка 56: Строка 52:
constants
constants
     className = "main".
     className = "main".
     classVersion = "1.0".
     classVersion = "1.6".
   
   
clauses
clauses
Строка 73: Строка 69:
predicates
predicates
     classInfo : core::classInfo.
     classInfo : core::classInfo.
domains
    language_D=
        en;
        ru.
   
   
properties
properties
    language_V:language_D.
     players_V:player*.
     players_V:player*.
     multiMode_V:boolean.
     multiMode_V:boolean.
Строка 86: Строка 76:
predicates
predicates
     run:().
     run:().
    addPlayer:(player Player).
end class game
end class game
   
   
Строка 101: Строка 89:
   
   
class facts
class facts
    language_V:language_D:=en.
     multiMode_V:boolean:=false.
     multiMode_V:boolean:=false.
   
   
clauses
clauses
     run():-
     run():-
        setLanguage(),
        humanInterface::setLanguage(language_V),
         Mode=chooseSingleOrMultiGame(),
         Mode=chooseSingleOrMultiGame(),
         setGameProperties(),
         setGameProperties(),
         competitors::involvePlayers(),
         involvePlayers(),
         if Mode=single_S then  
         if Mode=single_S then  
             playSingle()
             playSingle()
Строка 122: Строка 107:
         single_S;
         single_S;
         multi_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
class predicates
Строка 164: Строка 137:
   
   
/***************************
/***************************
  Players
Involving Players
***************************/
***************************/
class facts
class facts
     players_V:player*:=[].
     players_V:player*:=[].
   
   
class predicates
    involvePlayers:().
clauses
    involvePlayers():-
        createPlayers(1).
class predicates
    createPlayers:(positive PlayerNo).
clauses
    createPlayers(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,
            string::format("Possible types of players:\n%s\nPlayer #%s",PlayersDescriptor,toString(PlayerNo))
            ),
        not(PlayerType=""),
        try
            Player=createPlayerObject(toTerm(PlayerType)),
            Player:setName(toString(PlayerNo)),
            players_V:=list::append(players_V,[Player]),
            NewPlayerNo=PlayerNo+1
        catch _TraceID do
            humanInterface::announceSettingsError(humanInterface::errorPlayerType_S),
            NewPlayerNo=PlayerNo
        end try,
        !,
        createPlayers(NewPlayerNo).
    createPlayers(_PlayerNo).
/* Potential Players List*/
class predicates
    playerDescriptor:(positive No [out],string PlayerDescriptorSrc [out]) multi.
clauses
clauses
     addPlayer(Player):-
     playerDescriptor(1,human::playerDescriptor_C).
         players_V:=list::append(players_V,[Player]).
    playerDescriptor(2,computer1::playerDescriptor_C).
    playerDescriptor(3,computer2::playerDescriptor_C).
class predicates
    createPlayerObject:(positive)->player.
clauses
    createPlayerObject(1)=Player:-
        !,
        Player=human::new().
    createPlayerObject(2)=Player:-
        !,
        Player=computer1::new().
    createPlayerObject(3)=Player:-
         !,
        Player=computer2::new().
    createPlayerObject(_)=_Player:-
        exception::raise(classInfo,wrongInputException,[]).
class predicates
    wrongInputException:exception.
clauses
    wrongInputException
        (
        classInfo,
        predicate_Name(),
        ""
        ).
   
   
/***************************
/***************************
Строка 207: Строка 249:
                 !
                 !
             catch _TraceID1 do
             catch _TraceID1 do
                 humanInterface::announce(humanInterface::errorMustBeNumber_S,""),
                 humanInterface::announceSettingsError(humanInterface::errorMustBeNumber_S),
                 fail
                 fail
             end try,
             end try,
             if StartingPlayer>list::length(players_V) then
             if StartingPlayer>list::length(players_V) then
                 humanInterface::announce(humanInterface::errorStartingPlayer_S,""),
                 humanInterface::announceSettingsError(humanInterface::errorStartingPlayer_S),
                 fail
                 fail
             end if
             end if
Строка 244: Строка 286:
     playSingle(Player):-
     playSingle(Player):-
         inProgress_V=false,
         inProgress_V=false,
         humanInterface::showStage(),
         if game::multiMode_V=false then
        humanInterface::announce(humanInterface::starter_S,Player:name),
            humanInterface::showStage(),
            humanInterface::announceStarter(Player:name)
        end if,
         inProgress_V:=true,
         inProgress_V:=true,
         Player:move(),
         Player:move(),
Строка 290: Строка 334:
             noOfRounds_V:=toTerm(InputString)
             noOfRounds_V:=toTerm(InputString)
         catch _TraceID do
         catch _TraceID do
             humanInterface::announce(humanInterface::errorNoOfRounds_S,""),
             humanInterface::announceSettingsError(humanInterface::errorNoOfRounds_S),
             defineNoOfRounds()
             defineNoOfRounds()
         end try,
         end try,
Строка 311: Строка 355:
         humanInterface::reset(),
         humanInterface::reset(),
         PlayersNo=list::length(game::players_V),
         PlayersNo=list::length(game::players_V),
         humanInterface::announce(humanInterface::reportHeader_S,toString(PlayersNo*noOfRounds_V)),
         humanInterface::announce
        findAll
             (
             (
             PlayerResultList,
             humanInterface::report_S,
             (
             string::format("\nResults of % games:",toString(PlayersNo*noOfRounds_V))
                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
        Player=list::getMember_nd(game::players_V),
             ),
             PlayerWinsFirst=calculateWins(Player,true),
        humanInterface::announce(humanInterface::report_S,toString(PlayerResultListList)),
             PlayerWinsNext=calculateWins(Player,false),
            Report=string::format
                (
                "\nPlayer %:\n\t Wins Total % including:\n\t\tWhile moving first - \t%\n\t\tWhile moving next - \t% ",
                Player:name,
                toString(PlayerWinsFirst+PlayerWinsNext),
                toString(PlayerWinsFirst),
                toString(PlayerWinsNext)
                ),
            humanInterface::announce(humanInterface::report_S,Report),
         fail().
         fail().
     playMulti():-
     playMulti():-
Строка 346: Строка 393:
     playRound(0):-!.
     playRound(0):-!.
     playRound(NoOfRounds):-
     playRound(NoOfRounds):-
        humanInterface::announce(round_S,toString(noOfRounds_V-NoOfRounds+1)),
         seniourJudge::playSingle(starter_V),
         seniourJudge::playSingle(starter_V),
         playRound(NoOfRounds-1).
         playRound(NoOfRounds-1).
Строка 430: Строка 476:
clauses
clauses
     defineFieldSize():-
     defineFieldSize():-
         InputString=humanInterface::getInput(humanInterface::fieldSize_S,string::format("%s,%s",toString(maxColumn_P),toString(maxRow_P))),
         InputString=humanInterface::getInput
            (
            humanInterface::fieldSize_S,
            string::format("%s,%s",toString(maxColumn_P),toString(maxRow_P))
            ),
         not(InputString=""),
         not(InputString=""),
         try
         try
Строка 439: Строка 489:
             maxRow_P:=Y
             maxRow_P:=Y
         catch _TraceID do
         catch _TraceID do
             humanInterface::announce(humanInterface::errorFieldSize_S,""),
             humanInterface::announceSettingsError(humanInterface::errorFieldSize_S),
             defineFieldSize()
             defineFieldSize()
         end try,
         end try,
Строка 451: Строка 501:
clauses
clauses
     set(InputString):-
     set(InputString):-
         Cell=convertToCell(InputString),
         Cell=toTerm(InputString),
         handleInput (Cell).
         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
clauses
Строка 477: Строка 515:
         list::isMember(Cell,polyline_P),
         list::isMember(Cell,polyline_P),
         try  
         try  
             _=makePolyLine(Cell,polyline_P) % it will be an exception if wrong Cell, but we ignore it by failing
             _=makePolyLine(Cell,polyline_P)   % it will be an exception if wrong Cell,
                                                            % but we ignore it by failing
         catch _TraceID do
         catch _TraceID do
             fail
             fail
Строка 487: Строка 526:
         polyline_P:=makePolyLine(Cell,polyline_P),
         polyline_P:=makePolyLine(Cell,polyline_P),
         !,
         !,
         humanInterface::showStep(Cell,ordinary_S).
         if game::multiMode_V=false then
            humanInterface::showStep(Cell,ordinary_S)
        end if.
   
   
class predicates
class predicates
Строка 514: Строка 555:
         classInfo,
         classInfo,
         predicate_Name(),
         predicate_Name(),
         ""
         "the point % can not prolong the polyline!"
         ).
         ).
   
   
Строка 546: Строка 587:
end interface player
end interface player
   
   
/**************
/******************************************
   Text localization
   Class HumanInterface
**************/
******************************************/
interface polyLineText
class humanInterface
open core
open core
   
   
predicates
predicates
        getText:(humanInterface::actionID_D)->string Text.
  reset:().
end interface polyLineText
   
   
class polyLineTextRu:polyLineText
predicates
end class polyLineTextRu
    announceStartUp:().
   
   
implement polyLineTextRu
predicates
open core, humanInterface
    waitOK:().
    showStage:().
    showStep:(juniourJudge::cell,juniourJudge::stepType_D).
    getInput:(inputType_D,string StringParameter)->string InputString.
    getInput:(inputType_D)->string InputString.
   
   
clauses
predicates
    getText(TextID)=Text:-
     announceSettingsError:(choiceError_D).
        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
predicates
     classInfo : core::classInfo.
     announce:(announceID_D AnnounceID,string AnnounceText).
    announceStarter:(string Name).
    announceThinker:(string Name).
    announceWin:(string Name).
    announceLoss:(string Name).
    announceError:(string Description).
    announceError:().
   
   
domains
domains
     actionID_D=
     announceID_D=
        beginner_S;
        thinker_S;
        congratulation_S;
        sorryLoss_S;
        reportHeader_S;
        playerReport_S;
         report_S;
         report_S;
        starter_S.
   
   
         round_S;
domains
         starter_S;
    choiceError_D=
        errorPlayerType_S;
         errorMustBeNumber_S;
         errorstartingPlayer_S;
        errorFieldSize_S;
        errorNoOfRounds_S.
   
   
        win_S;
domains
        loss_S;
    inputType_D=
        singleOrMultipleChoice_S;
         fieldSize_S;
         fieldSize_S;
         playerStep_S;
         playerStep_S;
Строка 674: Строка 640:
         searchDepth_S;
         searchDepth_S;
         noOfRounds_S;
         noOfRounds_S;
         singleOrMulti_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
end class humanInterface
Строка 706: Строка 648:
   
   
constants
constants
     className = "humanInterface".
     cellMarkedOrdinary_C="*".
     classVersion = "1.0".
     cellMarkedWinner_C="O".
constants % messages
    thinker_C="% is thinking ...".
    beginner_C="First move done by: %".
    error_C="Error, % ".
    congratulation_C="Player % won!".
    sorryLoss_C="%,  Sorry, you loss :-(".
   
   
clauses
    gameOrCompetition_C="Please choose the mode (S or Enter - single game, other - multiple):".
     classInfo(className, classVersion).
     fieldSize_C="\nPlease enter the size of the board X,Y (% by default):".
    playerStep_C="Please enter your move as c(X,Y):".
    playerType_C="\n%. Please enter the player type (Enter - end of list):".
    playerName_C="\nPlease assign the name to the player (% proposed):".
    startingPlayer_C="\nWho moves the first (PlayerNo or Enter - end of the game)?:".
    searchDepth_C="\nChoose the depth of the prognosis (% - by default): ".
    noOfRounds_C="\nPlease enter the number of rounds (% by default):".
   
   
constants
    errorPlayerType_C="\nNo such player type exiasts! Enter - repeat input:".
     cellMarkedOrdinary_C="*".
    errorMustBeNumber_C="\nMust be number! Please repeat input:".
     cellMarkedWinner_C="O".
    errorstartingPlayer_C="\nNo such Player exiasts! Please repeat input:".
     errorFieldSize_C="\nWrong size of the board entered! Please repeat input:".
     errorNoOfRounds_C="\nWrong amount of rounds entered! Please repeat input:".
   
   
constants
constants
Строка 725: Строка 682:
     announceLine_C=starterLine_C+1.
     announceLine_C=starterLine_C+1.
     actionLine_C=announceLine_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
clauses
Строка 744: Строка 689:
     getInput(InputType,StringParameter)=Input:-
     getInput(InputType,StringParameter)=Input:-
         inputInvitation(InputType,StringParameter),
         inputInvitation(InputType,StringParameter),
        !,
         Input = console::readLine(),
         Input = console::readLine(),
         console::clearInput().
         console::clearInput().
    getInput(_InputType,_StringParameter)=_Input:-
        common_Exception::raise_error(classInfo,predicate_Name(),"InternalException. Extra alternative").
   
   
class predicates
class predicates
     inputInvitation:(actionID_D,string StringParameter) determ.
     inputInvitation:(inputType_D,string StringParameter).
clauses
clauses
     inputInvitation(playerStep_S,_StringParameter):-
     inputInvitation(playerStep_S,_StringParameter):-
         clearMessageArea(actionLine_C),
         clearMessageArea(actionLine_C),
         writeMessage(actionLine_C,"%",language_V:getText(playerStep_S)).
         writeMessage(actionLine_C,"%",playerStep_C).
     inputInvitation(playerName_S,StringParameter):-
     inputInvitation(playerName_S,StringParameter):-
         console::writef(language_V:getText(playerName_S),StringParameter).
         console::writef(playerName_C,StringParameter).
     inputInvitation(playerType_S,StringParameter):-
     inputInvitation(playerType_S,StringParameter):-
        hasDomain(string,PlayersDescriptor),
         console::writef(playerType_C,StringParameter).
        [PlayersDescriptor,PlayerNo]=toTerm(StringParameter),
         console::writef(language_V:getText(playerType_S),PlayersDescriptor,PlayerNo).
     inputInvitation(startingPlayer_S,StringParameter):-
     inputInvitation(startingPlayer_S,StringParameter):-
         console::write(StringParameter,language_V:getText(startingPlayer_S)).
         console::write(StringParameter,startingPlayer_C).
     inputInvitation(searchDepth_S,StringParameter):-
     inputInvitation(searchDepth_S,StringParameter):-
         console::writef(language_V:getText(searchDepth_S),StringParameter).
         console::writef(searchDepth_C,StringParameter).
     inputInvitation(fieldSize_S,StringParameter):-
     inputInvitation(fieldSize_S,StringParameter):-
         console::writef(language_V:getText(fieldSize_S),StringParameter).
         console::writef(fieldSize_C,StringParameter).
     inputInvitation(noOfRounds_S,StringParameter):-
     inputInvitation(noOfRounds_S,StringParameter):-
         console::writef(language_V:getText(noOfRounds_S),StringParameter).
         console::writef(noOfRounds_C,StringParameter).
     inputInvitation(singleOrMulti_S,_StringParameter):-
     inputInvitation(singleOrMulti_S,_StringParameter):-
         console::write(language_V:getText(singleOrMultipleChoice_S)).
         console::write(gameOrCompetition_C).
   
   
clauses
clauses
Строка 789: Строка 729:
   
   
clauses
clauses
     showStep(_Cell,_Type):-
     showStep(_Point,_Type):-
         game::multiMode_V=true,
         game::multiMode_V=true,
        clearMessageArea(actionLine_C),
         !.
        nextChar(char_V),
         !,
        writeMessage(actionLine_C,"%",char_V).
     showStep(juniourJudge::c(X,Y),_Type):-
     showStep(juniourJudge::c(X,Y),_Type):-
         console::setLocation(console_native::coord(horizontalSpace_C*X, verticalSpace_C*Y)),
         console::setLocation(console_native::coord(horizontalSpace_C*X, verticalSpace_C*Y)),
Строка 802: Строка 739:
     showStep(_Cell,juniourJudge::winner_S):-
     showStep(_Cell,juniourJudge::winner_S):-
         console::write(cellMarkedWinner_C).
         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
clauses
Строка 818: Строка 745:
   
   
clauses
clauses
     announce(reportHeader_S,Parameter):-
     announceStarter(_Name):-
         !,
         game::multiMode_V=true,
        console::writef(language_V:getText(reportHeader_S),Parameter).
         !.
    announce(report_S,PlayerResultListList):-
     announceStarter(Name):-
        !,
        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),
         clearMessageArea(starterLine_C),
         writeMessage(starterLine_C,language_V:getText(beginner_S),Name).
         writeMessage(starterLine_C,beginner_C,Name).
     announce(errorPlayerType_S,_IgnoredText):-
clauses
    announceSettingsError(errorPlayerType_S):-
        console::write(errorPlayerType_C),
        _=console::readLine().
    announceSettingsError(errorMustBeNumber_S):-
        console::write(errorMustBeNumber_C).
    announceSettingsError(errorStartingPlayer_S):-
        console::write(errorStartingPlayer_C).
    announceSettingsError(errorFieldSize_S):-
        console::write(errorFieldSize_C).
    announceSettingsError(errorNoOfRounds_S):-
        console::write(errorNoOfRounds_C).
clauses
     announce(report_S,Report):-
         !,
         !,
         console::write(language_V:getText(errorPlayerType_S)),
         console::write(Report).
    announce(_AnnounceID,_AnnounceText).
clauses
    waitOK():-
         _=console::readLine().
         _=console::readLine().
    announce(errorMustBeNumber_S,_IgnoredText):-
clauses
        !,
     announceError():-
        console::write(language_V:getText(errorMustBeNumber_S)).
         announceError("").
     announce(errorStartingPlayer_S,_IgnoredText):-
         !,
     announceError(ErrorText):-
        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),
         clearMessageArea(announceLine_C),
         writeMessage(announceLine_C,language_V:getText(error_S),ErrorText).
         writeMessage(announceLine_C,error_C,ErrorText).
    announce(errorWrongCell_S,InvalidData):-
        !,
clauses
        clearMessageArea(announceLine_C),
     announceWin(Name):-
        writeMessage(announceLine_C,language_V:getText(errorWrongCell_S),InvalidData).
     announce(win_S,Name):-
        !,
         clearMessageArea(announceLine_C),
         clearMessageArea(announceLine_C),
         clearMessageArea(actionLine_C),
         clearMessageArea(actionLine_C),
         writeMessage(announceLine_C,language_V:getText(congratulation_S),Name),
         writeMessage(announceLine_C,congratulation_C,Name),
         _ = console::readLine().
         _ = console::readLine().
     announce(loss_S,Name):-
        !,
     announceLoss(Name):-
         clearMessageArea(announceLine_C),
         clearMessageArea(announceLine_C),
         clearMessageArea(actionLine_C),
         clearMessageArea(actionLine_C),
         writeMessage(announceLine_C,language_V:getText(sorryLoss_S),Name),
         writeMessage(announceLine_C,sorryLoss_C,Name),
         _ = console::readLine().
         _ = console::readLine().
     announce(thinker_S,_Name):-
clauses
     announceThinker(_Name):-
         game::multiMode_V=true,
         game::multiMode_V=true,
         !.
         !.
     announce(thinker_S,Name):-
     announceThinker(Name):-
        !,
         clearMessageArea(announceLine_C),
         clearMessageArea(announceLine_C),
         clearMessageArea(actionLine_C),
         clearMessageArea(actionLine_C),
         writeMessage(actionLine_C,language_V:getText(thinker_S),Name).
         writeMessage(actionLine_C,thinker_C,Name).
    announce(_Any,_Name):-
        common_Exception::raise_error(classInfo,predicate_Name(),"InternalException. Extra alternative").
clauses
    waitOK():-
        _=console::readLine().
   
   
clauses
clauses
Строка 915: Строка 826:
end implement humanInterface
end implement humanInterface
   
   
/******************
/******************************************
   Class Competitors
   Class human
******************/
******************************************/
class competitors
class human:player
open core
open core
constants
    playerDescriptor_C="Human: Your strategy".
end class human
   
   
predicates
implement human
    involvePlayers:().
open core
   
   
end class competitors
facts
    name:string:="Hum_".
   
   
implement competitors
open core
clauses
clauses
     involvePlayers():-
     setName(ProposedId):-
         involvePlayers(1).
         name:=string::format("%s%s",name,ProposedId),
        Name=humanInterface::getInput(humanInterface::playerName_S,name),
        if not(Name="") then
            name:=Name
        end if.
   
   
class predicates
    involvePlayers:(positive PlayerNo).
clauses
clauses
     involvePlayers(PlayerNo):-
     move():-
         humanInterface::announceStartUp(),
         InputString=humanInterface::getInput(humanInterface::playerStep_S),
        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
         try
             Player=createPlayerObject(toTerm(PlayerType)),
             juniourJudge::set(InputString)
            Player:setName(toString(PlayerNo)),
         catch TraceID do
            game::addPlayer(Player),
             handleException(TraceID),
            NewPlayerNo=PlayerNo+1
             fail
         catch _TraceID do
             humanInterface::announce(humanInterface::errorPlayerType_S,""),
             NewPlayerNo=PlayerNo
         end try,
         end try,
         !,
         !.
         involvePlayers(NewPlayerNo).
    move():-
     involvePlayers(_PlayerNo).
         move().
clauses
     announceWin():-
        humanInterface::announceWin(name).
    announceLoss():-
        humanInterface::announceLoss(name).
   
   
   
   
class predicates
class predicates
     wrongInputException:exception.
     handleException:(exception::traceId TraceID).
clauses
    handleException(TraceID):-
        foreach Descriptor=exception::getDescriptor_nd(TraceID) do
            Descriptor = exception::descriptor(
                _ClassInfo1,
                exception::exceptionDescriptor(_ClassInfo2,_PredicateName,Description),
                _Kind,
                ExtraInfo,
                _GMTTime,
                _ExceptionDescription,
                _ThreadId),
            if
                ExtraInfo=[namedValue("data",string(CellPointer))]
            then
                ErrorMsg=string::format(Description,CellPointer),
                humanInterface::announceError(ErrorMsg)
            else
                humanInterface::announceError("")
            end if
        end foreach.
end implement human
/************************
  Class GenericComputer
************************/
interface genericComputer
    supports player
    supports polyLineBrain
predicates
    setPolyLineBrain:(polyLineBrain).
    stepCandidate: (juniourJudge::cell*,juniourJudge::cell* [out],juniourJudge::cell [out]) nondeterm.
end interface genericComputer
class genericComputer:genericComputer
open core, exception
end class genericComputer
implement genericComputer
    delegate interface polyLineBrain to polyLineBrain_V
open core
facts
    name:string:="Cmp_".
    polyLineBrain_V:polyLineBrain:=erroneous.
clauses
    setName(ProposedId):-
        name:=string::format("%s%s",name,ProposedId),
        Name=humanInterface::getInput(humanInterface::playerName_S,name),
        if not(Name="") then
            name:=Name
        end if.
clauses
    setPolyLineBrain(PolyLineBrainObject):-
        polyLineBrain_V:=PolyLineBrainObject,
        polyLineBrain_V:setGenericComputer(This).
clauses
    move():-
        humanInterface::announceThinker(name),
        Cell=resolveStep(),
        juniourJudge::set(toString(Cell)).
predicates
    resolveStep:()->juniourJudge::cell.
clauses
    resolveStep()=Cell:-
        Cell=successfulStep(juniourJudge::polyline_P),
        !.
    resolveStep()=Cell:-
        Cell=randomStep(),
        !.
    resolveStep()=juniourJudge::c(X+1,Y+1):-
        X=math::random(juniourJudge::maxColumn_P-1),
        Y=math::random(juniourJudge::maxRow_P-1).
clauses
    stepCandidate([Cell],[Cell,NewCell], NewCell):-
        juniourJudge::neighbour_nd(Cell, NewCell).
    stepCandidate([Left, RestrictingCell | PolyLine],[NewCell,Left, RestrictingCell| PolyLine], NewCell):-
        NewCell=juniourJudge::neighbourOutOfPolyLine_nd(Left,RestrictingCell).
    stepCandidate(PolyLine,list::reverse([NewCell,Left, RestrictingCell |PolyLineTail]),NewCell):-
        [Left, RestrictingCell |PolyLineTail] = list::reverse(PolyLine),
        NewCell=juniourJudge::neighbourOutOfPolyLine_nd(Left,RestrictingCell).
clauses
    announceWin():-
        humanInterface::announceWin(name).
clauses
    announceLoss():-
        humanInterface::announceLoss(name).
end implement genericComputer
/******************************************
  Interface PolylineBrain
******************************************/
interface polylineBrain
open core
predicates
    setGenericComputer:(genericComputer).
    successfulStep: (juniourJudge::cell*)->juniourJudge::cell nondeterm.
    randomStep:()->juniourJudge::cell determ.
end interface polyLineBrain
/******************************************
  Class computer1
******************************************/
class computer1:player
open core
constants
    playerDescriptor_C=polyLineBrain1::playerDescriptor_C.
end class computer1
implement computer1
    inherits genericComputer
open core
clauses
    new():-
        PolyLineBraneObj=polyLineBrain1::new(),
        setPolyLineBrain(PolyLineBraneObj).
end implement computer1
/******************************************
  Class PolylineBrain1
******************************************/
class polyLineBrain1:polyLineBrain
open core
predicates
    classInfo : core::classInfo.
constants
    playerDescriptor_C="Computer1: The full depth search strategy".
end class polyLineBrain1
implement polyLineBrain1
open core, exception
constants
    className = "polyLineBrain1".
    classVersion = "1.0".
clauses
    classInfo(className, classVersion).
facts
    genericComputer_V:genericComputer:=erroneous.
clauses
    setGenericComputer(GenericComputerObj):-
        genericComputer_V:=GenericComputerObj.
clauses
    successfulStep(PolyLine)=BestMove:-
        genericComputer_V:stepCandidate(PolyLine, _PolyLine1,BestMove),
        list::isMember(BestMove, PolyLine),
        !.
    successfulStep(PolyLine)=Cell:-
        genericComputer_V:stepCandidate(PolyLine, PolyLine1,Cell),
            not(_=successfulStep(PolyLine1)).
clauses
    randomStep()=Cell:-
        findAll(NewCell,genericComputer_V:stepCandidate(juniourJudge::polyline_P,_Polyline1, NewCell),CellCandidateListWithDuplicates),
        CellCandidateList=list::removeDuplicates(CellCandidateListWithDuplicates),
        not(CellCandidateList=[]),
        NoOfVariants=list::length(CellCandidateList),
        ChoiceNo=math::random(NoOfVariants-1),
        Cell=list::nth(ChoiceNo+1,CellCandidateList).
end implement polylineBrain1
/******************************************
  Class computer2
******************************************/
class computer2:player
open core
constants
    playerDescriptor_C=polyLineBrain2::playerDescriptor_C.
end class computer2
implement computer2
    inherits genericComputer
open core
clauses
    new():-
        PolyLineBraneObj=polyLineBrain2::new(),
        setPolyLineBrain(PolyLineBraneObj).
end implement computer2
/******************************************
  Class PolylineBrain2
******************************************/
class polyLineBrain2:polyLineBrain
open core
predicates
    classInfo : core::classInfo.
constants
    playerDescriptor_C="Computer2: Easy strategy. The prognosis depth is limited".
end class polyLineBrain2
implement polyLineBrain2
open core, exception
constants
    className = "polyLineBrain2".
    classVersion = "1.0".
clauses
    classInfo(className, classVersion).
facts
    depth_V:positive:=5.
    genericComputer_V:genericComputer:=erroneous.
clauses
    new():-
        defineSearchDepth().
clauses
    setGenericComputer(GenericComputerObj):-
        genericComputer_V:=GenericComputerObj.
predicates
    defineSearchDepth:().
clauses
    defineSearchDepth():-
        DepthStr=humanInterface::getInput(humanInterface::searchDepth_S,toString(depth_V)),
        not(DepthStr=""),
        !,
        try
            depth_V:=toTerm(DepthStr),
            if depth_V mod 2 = 0 then
                depth_V:=depth_V+1
            end if   
        catch _TraceID1 do
            humanInterface::announceSettingsError(humanInterface::errorMustBeNumber_S),
            defineSearchDepth()
        end try.
    defineSearchDepth().
predicates
    successfulStep: (integer Counter, juniourJudge::cell*)->juniourJudge::cell nondeterm.
clauses
clauses
     wrongInputException
     successfulStep(PolyLine)=BestMove:-
         (
         BestMove=successfulStep(depth_V,PolyLine).
         classInfo,
         predicate_Name(),
    successfulStep(Counter,PolyLine)=BestMove:-
         ""
         genericComputer_V:stepCandidate(PolyLine,_PolyLine1,BestMove),
         ).
         isStepSuccessful(Counter,PolyLine,BestMove),
         !.
    successfulStep(Counter,PolyLine)=Cell:-
         genericComputer_V:stepCandidate(PolyLine, PolyLine1,Cell),
            not(_=successfulStep(Counter-1,PolyLine1)).
   
   
class predicates
    playerDescriptor:(positive No [out],string PlayerDescriptorSrc [out]) multi.
clauses
clauses
     playerDescriptor(1,human::getPlayerDescriptor(game::language_V)).
     randomStep()=Cell:-
    playerDescriptor(2,computer0::getPlayerDescriptor(game::language_V)).
        findAll(NewCell,genericComputer_V:stepCandidate(juniourJudge::polyline_P,_Polyline1, NewCell),CellCandidateListWithDuplicates),
    playerDescriptor(3,computer1::getPlayerDescriptor(game::language_V)).
        CellCandidateList=list::removeDuplicates(CellCandidateListWithDuplicates),
    playerDescriptor(4,computer2::getPlayerDescriptor(game::language_V)).
        not(CellCandidateList=[]),
/*Include here lines corresponding to the Player Class*/
        NoOfVariants=list::length(CellCandidateList),
%    playerDescriptor(5,computer3::getPlayerDescriptor(game::language_V)).
        ChoiceNo=math::random(NoOfVariants-1),
        Cell=list::nth(ChoiceNo+1,CellCandidateList).
   
   
class predicates
class predicates
     createPlayerObject:(positive)->player.
     isStepSuccessful:(integer Counter,juniourJudge::cell* PolyLine,juniourJudge::cell BestMove) determ.
clauses
clauses
     createPlayerObject(1)=Player:-
     isStepSuccessful(_Counter,PolyLine,BestMove):-
         !,
         list::isMember(BestMove, PolyLine),
        Player=human::new().
         !.
  createPlayerObject(2)=Player:-
     isStepSuccessful(Counter,_PolyLine,_BestMove):-
        !,
         Counter<=1.
        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
end implement polylineBrain2
</vip>
</vip>
==Ссылки==
|enver=
[[Category:Проекты]]
[[en:Game Polyline. Release 7]]
[[Category:Игры]]
}}

Версия 14:27, 28 марта 2011

Учебный Проект. Релиз 7

Автор: Виктор Юхтенко. Email victor@pdc.spb.su

Очередная версия Учебного проекта, функциональной идеей которого является простая игра.

Правила игры ...

Цель

Демонстрация свойств языка Visual Prolog и простейших приемов программирования.

Функции

  • Механизм мультиязычности;
  • Индикация динамики процесса.

Код

  • Проверено на версии Visual Prolog 7.3 build 7302.
  • Код реорганизован для поддержки новых функций.

Установка

Если Вам нужен полный набор проектов серии Polyline (персональная версия), сгрузите и разархивируйте файлы архивов, пользуясь ссылками на форуме PDC ЗДЕСЬ

  • VipSpbSDK_PE_73_Examples_Polyline_1_14.zip
  • VipSpbSDK_PE_73_Tools_Polyline_1_14.zip]

в удобную для Вас директорию.

Коммерческая версия представлена в виде одного архива и может быть получена Здесь.

Оплата в любой из указанных валют. При оплате с рублевой кредитной карты валюта оплаты конвертируется в рубли по курсу банка-эмитента карты.

Директория с именем VipSpbSDK будет создана автоматически.

Если у Вас установлен VipSpbSDK, то следует открыть проект Examples\Polyline\Polyline1\Polyline7.prj

Если у Вас нет полного набора примеров из VipSpbSDK, то для помещения игры в проект необходимо:

  • Создать проект с пользовательским интерфейсом типа console
  • Построить проект
  • В построенном проекте заменить полностью код файла "main.pro" кодом, предложенным ниже.
  • Запустить вновь построение проекта. При построении проекта ответить на предложение о включении дополнительных пакетов в проект "Add All".

Если у Вас нет полного набора примеров из VipSpbSDK, то для помещения игры в проект необходимо:

  • Создать проект с пользовательским интерфейсом типа Console
  • В построенном проекте заменить полностью код файла "main.pro" кодом, предложенным ниже
  • Построить проект
  • Добавить в файл "main.pro" текст программы страницы Класс GenericComputer
  • Добавить в файл "main.pro" классы игроков с одновременной модификацией класса competitors

Запуск

Запуск приложения из среды по E или запустить исполняемое приложение из директории EXE.

/****************************************************
Copyright (c) Victor Yukhtenko
 
SpbSolutions/Examples/Polyline
 
Predicates, which represent the strategy
    neighbour_nd,
    neighbourOutOfPolyLine_nd,
    stepCandidate
based on solutions proposed by Elena Efimova
Predidcates
    successfulStep
modified
*****************************************************/
/*****************
  GOAL
*****************/
goal
    mainExe::run(main::run).
 
/**************
 Class Main
**************/
implement main
    open core
 
constants
    className = "main".
    classVersion = "1.6".
 
clauses
    classInfo(className, classVersion).
 
clauses
    run():-
        console::init(),   
        game::run().
 
end implement main
 
class game
open core
 
predicates
    classInfo : core::classInfo.
 
properties
    players_V:player*.
    multiMode_V:boolean.
 
predicates
    run:().
end class game
 
implement game
open core
 
constants
    className = "game".
    classVersion = "1.0".
 
clauses
    classInfo(className, classVersion).
 
class facts
    multiMode_V:boolean:=false.
 
clauses
    run():-
        Mode=chooseSingleOrMultiGame(),
        setGameProperties(),
        involvePlayers(),
        if Mode=single_S then 
            playSingle()
        else
            multiMode_V:=true,
            seniourJudge::playMulti()
        end if.
 
domains
    mode_D=
        single_S;
        multi_S.
 
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().
 
/***************************
 Involving Players
***************************/
class facts
    players_V:player*:=[].
 
class predicates
    involvePlayers:().
clauses
    involvePlayers():-
        createPlayers(1).
 
class predicates
    createPlayers:(positive PlayerNo).
clauses
    createPlayers(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,
            string::format("Possible types of players:\n%s\nPlayer #%s",PlayersDescriptor,toString(PlayerNo))
            ),
        not(PlayerType=""),
        try
            Player=createPlayerObject(toTerm(PlayerType)),
            Player:setName(toString(PlayerNo)),
            players_V:=list::append(players_V,[Player]),
            NewPlayerNo=PlayerNo+1
        catch _TraceID do
            humanInterface::announceSettingsError(humanInterface::errorPlayerType_S),
            NewPlayerNo=PlayerNo
        end try,
        !,
        createPlayers(NewPlayerNo).
    createPlayers(_PlayerNo).
 
/* Potential Players List*/ 
class predicates
    playerDescriptor:(positive No [out],string PlayerDescriptorSrc [out]) multi.
clauses
    playerDescriptor(1,human::playerDescriptor_C).
    playerDescriptor(2,computer1::playerDescriptor_C).
    playerDescriptor(3,computer2::playerDescriptor_C).
 
class predicates
    createPlayerObject:(positive)->player.
clauses
    createPlayerObject(1)=Player:-
        !,
        Player=human::new().
    createPlayerObject(2)=Player:-
        !,
        Player=computer1::new().
    createPlayerObject(3)=Player:-
        !,
        Player=computer2::new().
    createPlayerObject(_)=_Player:-
        exception::raise(classInfo,wrongInputException,[]).
 
class predicates
    wrongInputException:exception.
clauses
    wrongInputException
        (
        classInfo,
        predicate_Name(),
        ""
        ).
 
/***************************
 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::announceSettingsError(humanInterface::errorMustBeNumber_S),
                fail
            end try,
            if StartingPlayer>list::length(players_V) then
                humanInterface::announceSettingsError(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,
        if game::multiMode_V=false then
            humanInterface::showStage(),
            humanInterface::announceStarter(Player:name)
        end if,
        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::announceSettingsError(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::report_S,
            string::format("\nResults of % games:",toString(PlayersNo*noOfRounds_V))
            ),
        Player=list::getMember_nd(game::players_V),
            PlayerWinsFirst=calculateWins(Player,true),
            PlayerWinsNext=calculateWins(Player,false),
            Report=string::format
                (
                "\nPlayer %:\n\t Wins Total % including:\n\t\tWhile moving first - \t%\n\t\tWhile moving next - \t% ",
                Player:name,
                toString(PlayerWinsFirst+PlayerWinsNext),
                toString(PlayerWinsFirst),
                toString(PlayerWinsNext)
                ),
            humanInterface::announce(humanInterface::report_S,Report),
        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):-
        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::announceSettingsError(humanInterface::errorFieldSize_S),
            defineFieldSize()
        end try,
        !.
    defineFieldSize().
 
clauses
    isGameOver():-
        endOfGame_V=true.
 
clauses
    set(InputString):-
        Cell=toTerm(InputString),
        handleInput (Cell).
 
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),
        !,
        if game::multiMode_V=false then
            humanInterface::showStep(Cell,ordinary_S)
        end if.
 
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(),
        "the point % can not prolong the polyline!"
        ).
 
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
 
/******************************************
  Class HumanInterface
******************************************/
class humanInterface
open core
 
predicates
   reset:().
 
predicates
    announceStartUp:().
 
predicates
    waitOK:().
    showStage:().
    showStep:(juniourJudge::cell,juniourJudge::stepType_D).
    getInput:(inputType_D,string StringParameter)->string InputString.
    getInput:(inputType_D)->string InputString.
 
predicates
    announceSettingsError:(choiceError_D).
 
predicates
    announce:(announceID_D AnnounceID,string AnnounceText).
    announceStarter:(string Name).
    announceThinker:(string Name).
    announceWin:(string Name).
    announceLoss:(string Name).
    announceError:(string Description).
    announceError:().
 
domains
    announceID_D=
        report_S;
        starter_S.
 
domains
    choiceError_D=
        errorPlayerType_S;
        errorMustBeNumber_S;
        errorstartingPlayer_S;
        errorFieldSize_S;
        errorNoOfRounds_S.
 
domains
    inputType_D=
        fieldSize_S;
        playerStep_S;
        playerType_S;
        playerName_S;
        startingPlayer_S;
        searchDepth_S;
        noOfRounds_S;
        singleOrMulti_S.
 
end class humanInterface
 
implement humanInterface
open core
 
constants
    cellMarkedOrdinary_C="*".
    cellMarkedWinner_C="O".
 
constants % messages
    thinker_C="% is thinking ...".
    beginner_C="First move done by: %".
    error_C="Error, % ".
    congratulation_C="Player % won!".
    sorryLoss_C="%,  Sorry, you loss :-(".
 
    gameOrCompetition_C="Please choose the mode (S or Enter - single game, other - multiple):".
    fieldSize_C="\nPlease enter the size of the board X,Y (% by default):".
    playerStep_C="Please enter your move as c(X,Y):".
    playerType_C="\n%. Please enter the player type (Enter - end of list):".
    playerName_C="\nPlease assign the name to the player (% proposed):".
    startingPlayer_C="\nWho moves the first (PlayerNo or Enter - end of the game)?:".
    searchDepth_C="\nChoose the depth of the prognosis (% - by default): ".
    noOfRounds_C="\nPlease enter the number of rounds (% by default):".
 
    errorPlayerType_C="\nNo such player type exiasts! Enter - repeat input:".
    errorMustBeNumber_C="\nMust be number! Please repeat input:".
    errorstartingPlayer_C="\nNo such Player exiasts! Please repeat input:".
    errorFieldSize_C="\nWrong size of the board entered! Please repeat input:".
    errorNoOfRounds_C="\nWrong amount of rounds entered! Please repeat input:".
 
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.
 
clauses
    getInput(InputType)=Input:-
        Input=getInput(InputType,"").
 
    getInput(InputType,StringParameter)=Input:-
        inputInvitation(InputType,StringParameter),
        Input = console::readLine(),
        console::clearInput().
 
class predicates
    inputInvitation:(inputType_D,string StringParameter).
clauses
    inputInvitation(playerStep_S,_StringParameter):-
        clearMessageArea(actionLine_C),
        writeMessage(actionLine_C,"%",playerStep_C).
    inputInvitation(playerName_S,StringParameter):-
        console::writef(playerName_C,StringParameter).
    inputInvitation(playerType_S,StringParameter):-
        console::writef(playerType_C,StringParameter).
    inputInvitation(startingPlayer_S,StringParameter):-
        console::write(StringParameter,startingPlayer_C).
    inputInvitation(searchDepth_S,StringParameter):-
        console::writef(searchDepth_C,StringParameter).
    inputInvitation(fieldSize_S,StringParameter):-
        console::writef(fieldSize_C,StringParameter).
    inputInvitation(noOfRounds_S,StringParameter):-
        console::writef(noOfRounds_C,StringParameter).
    inputInvitation(singleOrMulti_S,_StringParameter):-
        console::write(gameOrCompetition_C).
 
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(_Point,_Type):-
        game::multiMode_V=true,
        !.
    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).
 
clauses
    announceStartUp():-
        reset().
 
clauses
    announceStarter(_Name):-
        game::multiMode_V=true,
        !.
    announceStarter(Name):-
        clearMessageArea(starterLine_C),
        writeMessage(starterLine_C,beginner_C,Name).
 
clauses
    announceSettingsError(errorPlayerType_S):-
        console::write(errorPlayerType_C),
        _=console::readLine().
    announceSettingsError(errorMustBeNumber_S):-
        console::write(errorMustBeNumber_C).
    announceSettingsError(errorStartingPlayer_S):-
        console::write(errorStartingPlayer_C).
    announceSettingsError(errorFieldSize_S):-
        console::write(errorFieldSize_C).
    announceSettingsError(errorNoOfRounds_S):-
        console::write(errorNoOfRounds_C).
 
clauses
    announce(report_S,Report):-
        !,
        console::write(Report).
    announce(_AnnounceID,_AnnounceText).
 
clauses
    waitOK():-
        _=console::readLine().
clauses
    announceError():-
        announceError("").
 
    announceError(ErrorText):-
        clearMessageArea(announceLine_C),
        writeMessage(announceLine_C,error_C,ErrorText).
 
clauses
    announceWin(Name):-
        clearMessageArea(announceLine_C),
        clearMessageArea(actionLine_C),
        writeMessage(announceLine_C,congratulation_C,Name),
        _ = console::readLine().
 
    announceLoss(Name):-
        clearMessageArea(announceLine_C),
        clearMessageArea(actionLine_C),
        writeMessage(announceLine_C,sorryLoss_C,Name),
        _ = console::readLine().
 
clauses
    announceThinker(_Name):-
        game::multiMode_V=true,
        !.
    announceThinker(Name):-
        clearMessageArea(announceLine_C),
        clearMessageArea(actionLine_C),
        writeMessage(actionLine_C,thinker_C,Name).
 
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 human
******************************************/
class human:player
open core
constants
    playerDescriptor_C="Human: Your strategy".
end class human
 
implement human
open core
 
facts
    name:string:="Hum_".
 
clauses
    setName(ProposedId):-
        name:=string::format("%s%s",name,ProposedId),
        Name=humanInterface::getInput(humanInterface::playerName_S,name),
        if not(Name="") then
            name:=Name
        end if.
 
clauses
    move():-
        InputString=humanInterface::getInput(humanInterface::playerStep_S),
        try
            juniourJudge::set(InputString)
        catch TraceID do
            handleException(TraceID),
            fail
        end try,
        !.
    move():-
        move().
 
clauses
    announceWin():-
        humanInterface::announceWin(name).
 
    announceLoss():-
        humanInterface::announceLoss(name).
 
 
class predicates
    handleException:(exception::traceId TraceID).
clauses
    handleException(TraceID):-
        foreach Descriptor=exception::getDescriptor_nd(TraceID) do
            Descriptor = exception::descriptor(
                _ClassInfo1,
                exception::exceptionDescriptor(_ClassInfo2,_PredicateName,Description),
                _Kind,
                ExtraInfo,
                _GMTTime,
                _ExceptionDescription,
                _ThreadId),
            if
                ExtraInfo=[namedValue("data",string(CellPointer))]
            then
                ErrorMsg=string::format(Description,CellPointer),
                humanInterface::announceError(ErrorMsg)
            else
                humanInterface::announceError("")
            end if
        end foreach.
 
end implement human
 
/************************
  Class GenericComputer
************************/
interface genericComputer
    supports player
    supports polyLineBrain
 
predicates
    setPolyLineBrain:(polyLineBrain).
    stepCandidate: (juniourJudge::cell*,juniourJudge::cell* [out],juniourJudge::cell [out]) nondeterm.
 
end interface genericComputer
 
class genericComputer:genericComputer
open core, exception
 
end class genericComputer
 
implement genericComputer
    delegate interface polyLineBrain to polyLineBrain_V
 
open core
 
facts
    name:string:="Cmp_".
    polyLineBrain_V:polyLineBrain:=erroneous.
 
clauses
    setName(ProposedId):-
        name:=string::format("%s%s",name,ProposedId),
        Name=humanInterface::getInput(humanInterface::playerName_S,name),
        if not(Name="") then
            name:=Name
        end if.
 
clauses
    setPolyLineBrain(PolyLineBrainObject):-
        polyLineBrain_V:=PolyLineBrainObject,
        polyLineBrain_V:setGenericComputer(This).
 
clauses
    move():-
        humanInterface::announceThinker(name),
        Cell=resolveStep(),
        juniourJudge::set(toString(Cell)).
 
predicates
    resolveStep:()->juniourJudge::cell.
clauses
    resolveStep()=Cell:-
        Cell=successfulStep(juniourJudge::polyline_P),
        !.
    resolveStep()=Cell:-
        Cell=randomStep(),
        !.
    resolveStep()=juniourJudge::c(X+1,Y+1):-
        X=math::random(juniourJudge::maxColumn_P-1),
        Y=math::random(juniourJudge::maxRow_P-1).
 
clauses
    stepCandidate([Cell],[Cell,NewCell], NewCell):-
        juniourJudge::neighbour_nd(Cell, NewCell).
    stepCandidate([Left, RestrictingCell | PolyLine],[NewCell,Left, RestrictingCell| PolyLine], NewCell):-
        NewCell=juniourJudge::neighbourOutOfPolyLine_nd(Left,RestrictingCell).
    stepCandidate(PolyLine,list::reverse([NewCell,Left, RestrictingCell |PolyLineTail]),NewCell):-
        [Left, RestrictingCell |PolyLineTail] = list::reverse(PolyLine),
        NewCell=juniourJudge::neighbourOutOfPolyLine_nd(Left,RestrictingCell).
 
clauses
    announceWin():-
        humanInterface::announceWin(name).
 
clauses
    announceLoss():-
        humanInterface::announceLoss(name).
 
end implement genericComputer
 
/******************************************
  Interface PolylineBrain
******************************************/
interface polylineBrain
open core
 
predicates
    setGenericComputer:(genericComputer).
    successfulStep: (juniourJudge::cell*)->juniourJudge::cell nondeterm.
    randomStep:()->juniourJudge::cell determ.
 
end interface polyLineBrain
 
/******************************************
  Class computer1
******************************************/
class computer1:player
open core
 
constants
    playerDescriptor_C=polyLineBrain1::playerDescriptor_C.
 
end class computer1
 
implement computer1
    inherits genericComputer
open core
 
clauses
    new():-
        PolyLineBraneObj=polyLineBrain1::new(),
        setPolyLineBrain(PolyLineBraneObj).
 
end implement computer1
 
/******************************************
  Class PolylineBrain1
******************************************/
class polyLineBrain1:polyLineBrain
open core
predicates
    classInfo : core::classInfo.
 
constants
    playerDescriptor_C="Computer1: The full depth search strategy".
 
end class polyLineBrain1
 
implement polyLineBrain1
open core, exception
 
constants
    className = "polyLineBrain1".
    classVersion = "1.0".
 
clauses
    classInfo(className, classVersion).
 
facts
    genericComputer_V:genericComputer:=erroneous.
 
clauses
    setGenericComputer(GenericComputerObj):-
        genericComputer_V:=GenericComputerObj.
 
clauses
    successfulStep(PolyLine)=BestMove:-
        genericComputer_V:stepCandidate(PolyLine, _PolyLine1,BestMove),
        list::isMember(BestMove, PolyLine),
        !.
    successfulStep(PolyLine)=Cell:-
        genericComputer_V:stepCandidate(PolyLine, PolyLine1,Cell),
            not(_=successfulStep(PolyLine1)).
 
clauses
    randomStep()=Cell:-
        findAll(NewCell,genericComputer_V:stepCandidate(juniourJudge::polyline_P,_Polyline1, NewCell),CellCandidateListWithDuplicates),
        CellCandidateList=list::removeDuplicates(CellCandidateListWithDuplicates),
        not(CellCandidateList=[]),
        NoOfVariants=list::length(CellCandidateList),
        ChoiceNo=math::random(NoOfVariants-1),
        Cell=list::nth(ChoiceNo+1,CellCandidateList).
 
end implement polylineBrain1
 
/******************************************
  Class computer2
******************************************/
class computer2:player
open core
constants
    playerDescriptor_C=polyLineBrain2::playerDescriptor_C.
 
end class computer2
 
implement computer2
    inherits genericComputer
open core
 
clauses
    new():-
        PolyLineBraneObj=polyLineBrain2::new(),
        setPolyLineBrain(PolyLineBraneObj).
 
end implement computer2
 
/******************************************
  Class PolylineBrain2
******************************************/
class polyLineBrain2:polyLineBrain
open core
predicates
    classInfo : core::classInfo.
 
constants
    playerDescriptor_C="Computer2: Easy strategy. The prognosis depth is limited".
 
end class polyLineBrain2
 
implement polyLineBrain2
open core, exception
 
constants
    className = "polyLineBrain2".
    classVersion = "1.0".
 
clauses
    classInfo(className, classVersion).
 
facts
    depth_V:positive:=5.
    genericComputer_V:genericComputer:=erroneous.
 
clauses
    new():-
        defineSearchDepth().
 
clauses
    setGenericComputer(GenericComputerObj):-
        genericComputer_V:=GenericComputerObj.
 
predicates
    defineSearchDepth:().
clauses
    defineSearchDepth():-
        DepthStr=humanInterface::getInput(humanInterface::searchDepth_S,toString(depth_V)),
        not(DepthStr=""),
        !,
        try
            depth_V:=toTerm(DepthStr),
            if depth_V mod 2 = 0 then
                depth_V:=depth_V+1
            end if    
        catch _TraceID1 do
            humanInterface::announceSettingsError(humanInterface::errorMustBeNumber_S),
            defineSearchDepth()
        end try.
    defineSearchDepth().
 
predicates
    successfulStep: (integer Counter, juniourJudge::cell*)->juniourJudge::cell nondeterm.
clauses
    successfulStep(PolyLine)=BestMove:-
        BestMove=successfulStep(depth_V,PolyLine).
 
    successfulStep(Counter,PolyLine)=BestMove:-
        genericComputer_V:stepCandidate(PolyLine,_PolyLine1,BestMove),
        isStepSuccessful(Counter,PolyLine,BestMove),
        !.
    successfulStep(Counter,PolyLine)=Cell:-
        genericComputer_V:stepCandidate(PolyLine, PolyLine1,Cell),
            not(_=successfulStep(Counter-1,PolyLine1)).
 
clauses
    randomStep()=Cell:-
        findAll(NewCell,genericComputer_V:stepCandidate(juniourJudge::polyline_P,_Polyline1, NewCell),CellCandidateListWithDuplicates),
        CellCandidateList=list::removeDuplicates(CellCandidateListWithDuplicates),
        not(CellCandidateList=[]),
        NoOfVariants=list::length(CellCandidateList),
        ChoiceNo=math::random(NoOfVariants-1),
        Cell=list::nth(ChoiceNo+1,CellCandidateList).
 
class predicates
    isStepSuccessful:(integer Counter,juniourJudge::cell* PolyLine,juniourJudge::cell BestMove) determ.
clauses
    isStepSuccessful(_Counter,PolyLine,BestMove):-
        list::isMember(BestMove, PolyLine),
        !.
    isStepSuccessful(Counter,_PolyLine,_BestMove):-
        Counter<=1.
 
end implement polylineBrain2