Abnormal programming
Open source
Mathematics
September 6 2013

Scilab — от поиска факториала до крестиков-ноликов

Добрый вечер друзья, сегодня пятница и я по традиции хотел бы поделиться с Вами своими изысканиями.
Забавная сложилась ситуация. Те немногие программисты (люди связанные с программированием), которых я знаю лично, никогда не писали игры, а люди которые от понятия «профессиональный программист», далеки примерно так же как белый медведь от принципов гуманизма, нет нет да сварганят какую-нибудь жуткую неиграбельную поделку.
Один из названных выше людей — Я.
В этой статье хочу убить двух зайцев немного рассказать людям о пакете прикладных математических программ Scilab, а заодно продемонстрировать его функции нестандартным образом
Сегодня я расскажу вам, о том, как делал крестики нолики в Scilab. За подробностями милости прошу под кат.

image

За картинку спасибо DrZugrik


Начнем с того, что я не программист, совcем не программист, очень очень очень не программист.
Именно поэтому предлагаю не принимать данную статью, как руководство к действию. Данный пост я пишу только «just for fun» ну и отчасти для популяризации Scilab.
Исходный файл скрипта выложен на GitHub , так что если у кого-то возникнет желание улучшить код, то я только за.

Итак для начала краткая справка. Что же такое Scilab?
Подробный ответ на этот вопрос можно узнать на Википедии или на официальном сайте сообщества
Если рассказать своими словами – то Scilab, это открытий аналог Matlab. С очень похожим синтаксисом, с похожими процедурами (многие процедуры Matlab имеют свой аналог в Scilab), Интерфейс самой свежей Scilab 5.4.1, чем-то отдаленно напоминает Matlab пятилетней давности, теперь в нем вполне комфортно работать. Ну и самое главное Scilab имеет схожие возможности, безусловно меньшие чем у коммерческого гиганта, но все же для студента, начинающего ученого или просто любопытного инженера вполне достаточные. У Scilab есть свой аналог Simulink (правда явно уступающий), также можно подключать различные модули, например Maxima для символьных вычислений (у меня работало не очень надежно, но работало).Scilab есть под Windows и Linux, есть исходники, выпускается под открытой лицензией. Чем не замена пиратским копиям Matlab, установленным в колледжах и университетах?
Пример работы пакета прикладных математических программ можно увидеть на скриншотах под спойлером.

Интерфейс, графики и факториалы
image
графики в Scilab

image
пример функции — нахождение факториала


Безусловно освоить Scilab, возможно будет немного сложнее. Он менее отлажен, присутствуют баги да и методик работы с ним конечно меньше, чем с большим братом, но со временам все больше и больше ответов на потенциальные вопросы можно найти в интернете и в руководствах к программе.
Руководствами мы сейчас кстати и запасемся. Для написания крестиков ноликов мне понадобились Руководство по работе с пакетом SCILAB .
Создание графических приложений в среде Scilab,

ну и еще не помешает Scilab Решение инженерных и математических задач

Какая стояла задача.
С помощью возможностей по созданию графических интерфейсов в Scilab, написать простенькие крестики нолики для игры с компьютером.

Исходный код (выложены на GitHub ) представлен под спойлером

Если вкратце его описать, то вначале создается графическое окно, на нем размещается 9 кнопок игрового поля, текстовая метка и кнопка перезапуска. При нажатии на кнопку на игровом поле начинается игра. Искусственный интеллект, чисто с потолка берет значение от 1 до 9 и если оно свободно «ходит» туда, если нет копает дальше. В конце каждого обработчика нажатия, вызывается проверка выполнения условия победы (ячейки поля представляем как матрицу и всячески над ней издеваемся) В итоге получились простенькие крестики нолики для игры с AI, который в ходе тестов иногда меня неожиданно обыгрывал.

Выглядит это как-то так:

Исходный код
// Tick-tack-toe
//Tic Tac Toe, on the basis of scilab
//Start here

global ffield;  
global Win;
ffield=0;

//the creation of the game window
mw=figure();   
set(mw,'position',[20,40,500,450]);
set(mw,'figure_name','Tick-tack-toe');

//status Bar
label1=uicontrol('Style', 'text', 'Position', [80,400,250,20], 'String',..
'Game in progress (click on the square button)','HorizontalAlignment','left');
//the creation of the restart button
ubutton_c=uicontrol(mw,'Style','pushbutton','position',[80,380,120,20]..
,'String','Restart game','CallBack','newgame()');

//the creation of the playing field
ubutton=list([1:9]);
for i=1:9 
    num=string(i)
    y=ceil(i/3);
    x=i-((y-1)*3);
    ubutton(i)=uicontrol(mw,'Style','pushbutton','position',[80*x+2,80*y,80,80]..
    ,'String',' ','CallBack','press_button('+num+')');
end



function y=press_button(button_num)
    //gaming activities
    global ffield;
    global Win;
  
    // Human
    Button_Value=get(ubutton(button_num),'String');
    if Button_Value==" " then
        set(ubutton(button_num),'String',"X");
        ffield=ffield+1;
    end
    // AI 
    if ffield<9 then 
        ct=comp_turn();  //get random action of AI
        buf=get(ubutton(ct),'String');
        while buf ~= " " do
            ct=comp_turn();  //get random action of AI
            buf=get(ubutton(ct),'String');
        end
    
        set(ubutton(ct),'String',"0"); // Ai chooses cell
    end
        ffield=ffield+1;  //counter filled cells
        Winner() //find game winner
endfunction

function R=comp_turn()
    // Computer opponent action (random action)
    R = grand(1,1,"poi",4);
    if R>9 then R=9;    end;
    if R<1 then R=1;    end;
endfunction

function Winner()
    //find game winner function
    
    res=0;
    pw=0;
    cw=0;
    plfield=hypermat([3,3]);   // results matrix for human
    cmfield=hypermat([3,3]);   // results matrix for AI
    
    // check game field
    for ck=1:9 Button_Value=get(ubutton(ck),'String');
        j=ceil(ck/3);
        i=ck-((j-1)*3);
        if  Button_Value=="X"  then plfield(j,i)=1;  end 
        if  Button_Value=="0" then cmfield(j,i)=1; end 
    end   


    // check human results
    pb=pob_diag(plfield,3) ;//processing second diag.
    sm=prod(plfield,1)+prod(plfield,2)';//processing  matrix
    if sum(sm)==1 then res=1;   end; //check winning the hor. and vert. field
    if diag(plfield,0)==1 then res=1;   end; //check winning field main diag.
    if  pb==1 then res=1;   end; //check winning field second diag.
    
    // check AI results
    pb=pob_diag(cmfield,3) //processing second diag.
    sm=prod(cmfield,1)+prod(cmfield,2)';//processing matrix
    if sum(sm)==1 then res=2;   end; // check winning the hor. and vert. field
    if diag(cmfield,0)==1 then res=2;   end; //check winning field main diag.
    if  pb==1 then res=2;   end; //check winning field second diag.

 
    //  Deciding the winner
    if  res==1 then set(label1,'String',"You Win");   end 
    if  res==2 then set(label1,'String',"Computer Win");   end 
    if  (ffield>=9) & (res==0) then set(label1,'String',"No Winner");   end 
endfunction

function mult=pob_diag(A,N)
      //  analysis of the secondary diagonal matrix
    mult=1;
    for i=1:N

        mult=mult*A(i,N+1-i);
    end
endfunction

function mult=find_one(Win)
   // analysis of the columns of the matrix
    mult=1;
    prod(Win,1)+prod(Win,2)'
    for i=1:2
        mult=mult+i;
    end
endfunction

function newgame()
    // restart game (reset values)
    
    global ffield;
    global Win;
    global res;
    for i=1:9 
        y=ceil(i/3);
        x=i-((y-1)*3);
        set(ubutton(i),'String',' ');
    end;
    ffield=0;
    res=0
    Win=0;
    set(label1, 'String','Game in progress (click on the square button)');
endfunction



image

Безусловно код плохой, но надеюсь, что я смогу кого-нибудь мотивировать на изучение этого безусловно полезного математического инструмента.
Всем хорошей пятницы и прекрасных выходных :)
+21
16.4k 53
Comments 9
Top of the day