unit uGame4;
///////////////////////////////////
// версия 1,0
///////////////////////////////////
// модуль задания
// "Сравнение двух карт"
///////////////////////////////////

interface

procedure Game4Draw;
procedure Game4Init;
procedure Game4Process;

procedure EndTask;

implementation

uses uGeneralData,OMEGA,uGame,uGUI,uEndTask;

var MenuPanel:tMenuPanel;

    Card1,Card2:tCard;
    time,timestart:double;

    q1,q2,q3:real;

procedure Game4Init;
var DF:textfile;
    i1,i2:integer;
begin
// делаем меню
MenuPanel.Init('menupanel',0,0,158,Scrh);
// и добовляем в него кнопки
MenuPanel.AddBtn('в меню','buttoncirclmenu','bbackmenu',10,10,true,font);
MenuPanel.AddBtn('выход','buttoncirclnormal','bquit',10,scrh-138,true,font);
MenuPanel.AddBtn('проверить задание','buttoncirclnormal','bgotask',10,300,true,font);

// загружаем параметры задания по соответствующему типу и сложности
assignfile(DF,Dfld+'tasks\'+SceneName+'.txt');
reset(DF);
// задаём коэфициенты очков
readln(DF,q1,q2,q3);
// задаём параметры первой карты
readln(DF,Card1.sizex,Card1.sizey);
readln(DF,Card1.x,Card1.y);
Card1.Init;
// задаём параметры второй карты
readln(DF,Card2.sizex,Card2.sizey);
readln(DF,Card2.x,Card2.y);
Card2.Init;
// загружаем время выполнения задания
readln(DF,time);
// загрузка закончена
closefile(DF);

// заполняем карты случайно
// вероятность того, что 10<random(20) примерно 50/50
// так что карты будут примерно на половину состоять из дырок (т.е. тёмных точек
// в дальнейшем можно сдвинуть равновесие в одну или другую сторону
randomize;
Card1.x:=((ScrW-158)-(card1.sizex*16+56)) div 2+158;
for i1:=1 to card1.sizex do
 for i2:=1 to card1.sizey do begin
  card1.data[i1,i2,1]:=10<random(20);
  card1.data[i1,i2,2]:=false;
 end;
// то же для второй карты
randomize;
Card2.x:=((ScrW-158)-(card2.sizex*16+56)) div 2+158;
for i1:=1 to card2.sizex do
 for i2:=1 to card2.sizey do begin
  card2.data[i1,i2,1]:=10<random(20);
  card2.data[i1,i2,2]:=false;
 end;

//обнуляем результаты тренировки
rezult:=0;
eror:=0;
speed:=0;

//получаем время начала игры
timestart:=U_GetTime;

end;

procedure Game4Draw;
var str:PChar;
    t,t1,t2:integer;
begin

//на столе рисуем таймер
str:=PChar('времени осталось - '+U_IntToStr(trunc(time)-(trunc(U_GetTime-timestart) div 1000) mod 1000));
t:=trunc(Text_GetWidth(font,str,1,0)); //узнаём ширину текста
t1:=((scrw-158)-t) div 2+158;
t2:=5;
Pr2D_Rect(t1,t2,(t+20)*((trunc(U_GetTime-timestart) div 1000) mod 1000)/time,20,$003B7D,255,PR_Fill );
DrawGWind(t1,t2,t+20,20,200);
Text_Draw(font,10+t1,t2,str,1,0,255,$003B7D);

Card1.Draw;
Card2.Draw;
//если курсор в рабочих пределах второй карты, на соответствуещем отверстии первой карты рисуем выделение
if ((mouse_x>card2.x+32) and (mouse_x<card2.x+card2.sizex*16+32))
and ((mouse_y>card2.y+32) and (mouse_y<card2.y+card2.sizey*16+32))
then begin
//узнаём над каким отверстием карты находится курсор
 t1:=mouse_x-card2.x-32;
 t2:=mouse_y-card2.y-32;
 t1:=t1 div 16+1;
 t2:=t2 div 16+1;
 DrawFWind(2,card1.x+24+t1*16,card1.y+23+t2*16,6,6);
 DrawFWind(2,card2.x+24+t1*16,card2.y+23+t2*16,6,6);
end;

MenuPanel.Draw;

end;

procedure Game4Process;
var t1,t2:integer;
begin

MenuPanel.Process;

//если щёлкаем на каком либо отверстии второй карты
//то выделяем его
if ((mouse_x>card2.x+32) and (mouse_x<card2.x+card2.sizex*16+32))
and ((mouse_y>card2.y+32) and (mouse_y<card2.y+card2.sizey*16+32))
and (mouse_press(m_lbutton)) then begin
 t1:=mouse_x-card2.x-32;
 t2:=mouse_y-card2.y-32;
 t1:=t1 div 16+1;
 t2:=t2 div 16+1;
 card2.data[t1,t2,2]:=not card2.data[t1,t2,2];
end;

// проверяем нажатия кнопок меню
if (col_pointinaabb(mouse_x,mouse_y,@MenuPanel.Btn[1].c1))
 and (mouse_press(m_lbutton)) then GoToMenu;

if (col_pointinaabb(mouse_x,mouse_y,@menupanel.Btn[2].c1))
 and (mouse_press(m_lbutton)) then Oe_Quit;

if (col_pointinaabb(mouse_x,mouse_y,@menupanel.Btn[3].c1))
 and (mouse_press(m_lbutton)) then EndTask;

//разница во времени между временим на выполнение и уже пройденым
//уже пройденое в сек. = trunc(U_GetTime-timestart) div 1000
if (trunc(time)-(trunc(U_GetTime-timestart) div 1000) mod 1000)<=0 then EndTask;

end;

procedure EndTask;
var t1,t2:integer;
    score,t:integer;
begin
//максимальные результат равен перемножению размеров карты в точках
score:=card1.sizex*card2.sizey;
//ошибок пока небыло
t:=0;

//если точки карты равны, то отнимаем их из максимального результата
//этодаёт кол-во неравных точек
for t1:=1 to card1.sizex do
 for t2:=1 to card1.sizey do
  if (card1.data[t1,t2,1]=card2.data[t1,t2,1]) then score:=score-1;

for t1:=1 to card1.sizex do
 for t2:=1 to card1.sizey do
 begin
//если точки карты неравны, и мы не отметили их на второй карты,
//то из результата отнимаем их
  if (not card1.data[t1,t2,1]=card2.data[t1,t2,1])
      and not card2.data[t1,t2,2] then score:=score-1;
//если точки не равны, а мы не отметили это
//или если точки равны, а мы отметили их как неравные
//увиличиваем ошибку
  if (card1.data[t1,t2,1]<>card2.data[t1,t2,1])
      xor card2.data[t1,t2,2] then t:=t+1;
end;

rezult:=trunc(q1*score);
eror:=trunc(q3*t);
if (trunc(time)-(trunc(U_GetTime-timestart) div 1000) mod 1000)>0 then
 Speed:=trunc(q2*(trunc(time)-(trunc(U_GetTime-timestart) div 1000) mod 1000)-q3*t)
 else Speed:=0;

if trening then gscene:=sTraining else begin
//если в режиме игры, то запоминаем результат
//в результаты игрока
 Player.Experience:=Player.Experience+rezult;
 Player.Accuracy:=Player.Accuracy+eror;
 if (trunc(time)-(trunc(U_GetTime-timestart) div 1000) mod 1000)>0 then
  Player.Speed:=Player.Speed+trunc(q2*(trunc(time)-(trunc(U_GetTime-timestart) div 1000) mod 1000)-q3*t)
 else if q2*Player.Speed-eror>0 then Player.Speed:=trunc(q2*Player.Speed-eror);
 EndTaskB:=true;
 EndTaskInit;
end;

end;

end.
