Доступ к готовым решениям

Переход в группу "Пользователь"

300.00 ₽
Одноразовый платёж
Быстрый переход в группу "Пользователи", без надобности написания постов и ожидания.

Покупка дает возможность:
Быть полноправным участником форума
Нормальное копирование кода
Создавать темы
Скачивать файлы
Доступ к архиву Pawno-Info

Мануал Крестики-нолики [9x9]

Статус
В этой теме нельзя размещать новые ответы.

Prolific

Специалист
Опять же делал для конкурса.
Предисловие. Просмотрев пару работ, по крайней мере те, кто выложил, пришел к выводу, что я сильно ленивый, чтобы писать кучу комбинаций в массив, я не лентяй, чтобы делать проверку для 9 клеток и я не гонюсь за сверх оптимизацией. Согласен, проверка массивом будет работать гораздо быстрее, но для переписывания всех комбинаций в массив затрат умственных сил нужно меньше и, что самое главное скрипт не является универсальным. Если порядок матрицы увеличит на один, уже нужно будет думать, тогда как мои алгоритмы нуждаются только в ограничениях и мелких изменениях. Я не оправдываюсь, а лишь описываю свой подход к решению проблем. Есть несколько лишних переменных, но делал я их для читабельности и чтобы не запутаться. Насчет дизайна я и не буду даже говорить, менять правила в середине конкурса нечестно (оказывается не только в середине), но это уже совсем другая история. Ну и собственно оценивайте:
PHP:
//Крестики VS нолики By Prolific

#include <a_samp>
#include <dc_cmd>
#include <sscanf2>

new PlayerText: kvadrat[MAX_PLAYERS][81];
new PlayerText: text[MAX_PLAYERS][81];
new PlayerText: Exit[MAX_PLAYERS];
new Text: karkas[2];// в конкурсе размерность была 6, забыл исправить
new score[MAX_PLAYERS];//Счет игрока.
new kletka[MAX_PLAYERS][81];//Значение в клетке.
new type[MAX_PLAYERS char];//Крестик или нолик у игрока.
new PlayerText: names[MAX_PLAYERS][2];//Имена игроков в заголовке.
new PlayerText: scores[MAX_PLAYERS][2];//Счеты игроков в заголовке.
new bool:hod[MAX_PLAYERS];

public OnFilterScriptInit()
{
	print("\n--------------------------------------");
	print("       Krest and null By Prolific       ");
	print("--------------------------------------\n");
	
	karkas[0] = TextDrawCreate(602.644226, 166.000000, "usebox");
	TextDrawLetterSize(karkas[0], 0.000000, 24.312965);
	TextDrawTextSize(karkas[0], 381.250366, 255.500000);
	TextDrawAlignment(karkas[0], 1);
	TextDrawColor(karkas[0], 0);
	TextDrawUseBox(karkas[0], true);
	TextDrawBoxColor(karkas[0], 102);
	TextDrawSetShadow(karkas[0], 0);
	TextDrawSetOutline(karkas[0], 0);
	TextDrawFont(karkas[0], 0);
	
	karkas[1] = TextDrawCreate(604.049804, 132.166656, "usebox");
	TextDrawLetterSize(karkas[1], 0.000000, 28.266670);
	TextDrawTextSize(karkas[1], 379.844787, 0.000000);
	TextDrawAlignment(karkas[1], 1);
	TextDrawUseBox(karkas[1], true);
	TextDrawBoxColor(karkas[1], -5963521);
	TextDrawFont(karkas[1], 0);
	return 1;
}

public OnPlayerClickTextDraw(playerid, Text:clickedid)
{
    if(clickedid == Text: INVALID_TEXT_DRAW && type{playerid})
	{
		ShowPlayerDialog(playerid, 0, 0, "{ffffff}Выход", "{ffffff}Вы действительно хотите закончить игру?", "Да", "Нет");
        SelectTextDraw(playerid, 102);
	}
	return 1;
}

public OnPlayerClickPlayerTextDraw(playerid, PlayerText:playertextid)
{
    if(playertextid == Exit[playerid]) return ShowPlayerDialog(playerid, 0, 0, "{ffffff}Выход", "{ffffff}Вы действительно хотите закончить игру?", "Да", "Нет");
    for(new i; i < 81; i++)
    {
        if(playertextid == kvadrat[playerid][i])
		{
		    if(!hod[playerid]) return SendClientMessage(playerid, -1, "Сейчас не ваш ход!");
		    if(kletka[playerid][i]) return SendClientMessage(playerid, -1, "Эта клетка занята!");
		    hod[playerid] = false;
		    hod[GetPVarInt(playerid,"SOPERNIK")] = true;
		    UpdateKletka(playerid, i);
		}
    }
    
	return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
    switch(dialogid)
	{
	    case 0:
	    {
	        if(response)
			{
			    new playerid2 = GetPVarInt(playerid, "SOPERNIK");
			    HidePanel(playerid);
			    HidePanel(playerid2);
			}
	    }
	    case 1:
	    {
	        if(response)
	        {
	            new playerid2 = GetPVarInt(playerid,"SOPERNIK");
	            ShowPanel(playerid);
	            ShowPanel(playerid2);
	            SetPVarInt(playerid2, "SOPERNIK", playerid);
	            type{playerid} = 2;
	            type{playerid2} = 1;
	            score[playerid] = 0;
	            score[playerid2] = 0;
	            UpdateNames(playerid);
	            UpdateScores(playerid);
	            if(random(2)) hod[playerid] = true;
	            else hod[playerid2] = true;
	            return 1;
	        }
			else
			{
			    SendClientMessage(GetPVarInt(playerid,"SOPERNIK"), -1, "Игрок отказался играть.");
			    DeletePVar(playerid, "SOPERNIK");
			}
	    }
	}
	return 1;
}

public OnPlayerConnect(playerid)
{
    new Float:x = 389.0, Float:y = 173.0;
	for(new i, k; i < 9; i++)
	{
	    for(new j; j < 9; j++)
	    {
		    kvadrat[playerid][k] = CreatePlayerTextDraw(playerid, x, y, "LD_SPAC:white");
			PlayerTextDrawTextSize(playerid, kvadrat[playerid][k], 22.0, 22.0);
			PlayerTextDrawColor(playerid, kvadrat[playerid][k], -1);
			PlayerTextDrawFont(playerid, kvadrat[playerid][k], 4);
			PlayerTextDrawSetSelectable(playerid, kvadrat[playerid][k], 1);
			
			text[playerid][k] = CreatePlayerTextDraw(playerid, x + 12.0, y, "_");
			PlayerTextDrawLetterSize(playerid, text[playerid][k], 0.609297, 2.317500);
			PlayerTextDrawAlignment(playerid, text[playerid][k], 2);
			PlayerTextDrawColor(playerid, text[playerid][k], 255);
			PlayerTextDrawSetShadow(playerid, text[playerid][k], 0);
			PlayerTextDrawSetOutline(playerid, text[playerid][k], 0);
			PlayerTextDrawBackgroundColor(playerid, text[playerid][k], 51);
			PlayerTextDrawFont(playerid, text[playerid][k], 2);
			PlayerTextDrawSetProportional(playerid, text[playerid][k], 1);
			
			x += 23.0;
			k++;
		}
		x = 389.0;
		y += 23.0;
	}
    Exit[playerid] = CreatePlayerTextDraw(playerid, 581.903198, 133.000000, "LD_BEAT:cross");
	PlayerTextDrawTextSize(playerid, Exit[playerid], 17.335327, 17.500000);
	PlayerTextDrawAlignment(playerid, Exit[playerid], 1);
	PlayerTextDrawColor(playerid, Exit[playerid], -2640156);
	PlayerTextDrawFont(playerid, Exit[playerid], 4);
	PlayerTextDrawSetSelectable(playerid, Exit[playerid], 1);
	
	names[playerid][0] = CreatePlayerTextDraw(playerid, 383.250701, 127.166717, "_");
	PlayerTextDrawLetterSize(playerid, names[playerid][0], 0.251815, 1.850833);
	PlayerTextDrawAlignment(playerid, names[playerid][0], 1);
	PlayerTextDrawColor(playerid, names[playerid][0], -1);
	PlayerTextDrawSetShadow(playerid, names[playerid][0], 0);
	PlayerTextDrawSetOutline(playerid, names[playerid][0], 0);
	PlayerTextDrawBackgroundColor(playerid, names[playerid][0], 51);
	PlayerTextDrawFont(playerid, names[playerid][0], 2);
	PlayerTextDrawSetProportional(playerid, names[playerid][0], 1);

 	names[playerid][1] = CreatePlayerTextDraw(playerid, 383.313720, 142.750030, "_");
	PlayerTextDrawLetterSize(playerid, names[playerid][1], 0.251814, 1.850833);
	PlayerTextDrawAlignment(playerid, names[playerid][1], 1);
	PlayerTextDrawColor(playerid, names[playerid][1], -1);
	PlayerTextDrawSetShadow(playerid, names[playerid][1], 0);
	PlayerTextDrawSetOutline(playerid, names[playerid][1], 0);
	PlayerTextDrawBackgroundColor(playerid, names[playerid][1], 51);
	PlayerTextDrawFont(playerid, names[playerid][1], 2);
	PlayerTextDrawSetProportional(playerid, names[playerid][1], 1);

	scores[playerid][0] = CreatePlayerTextDraw(playerid, 514.563354, 127.166717, ": 01");
	PlayerTextDrawLetterSize(playerid, scores[playerid][0], 0.251814, 1.850833);
	PlayerTextDrawAlignment(playerid, scores[playerid][0], 1);
	PlayerTextDrawColor(playerid, scores[playerid][0], -1);
	PlayerTextDrawSetShadow(playerid, scores[playerid][0], 0);
	PlayerTextDrawSetOutline(playerid, scores[playerid][0], 0);
	PlayerTextDrawBackgroundColor(playerid, scores[playerid][0], 51);
	PlayerTextDrawFont(playerid, scores[playerid][0], 2);
	PlayerTextDrawSetProportional(playerid, scores[playerid][0], 1);

	scores[playerid][1] = CreatePlayerTextDraw(playerid, 514.563354, 142.750030, ": 02");
	PlayerTextDrawLetterSize(playerid, scores[playerid][1], 0.251814, 1.850833);
	PlayerTextDrawAlignment(playerid, scores[playerid][1], 1);
	PlayerTextDrawColor(playerid, scores[playerid][1], -1);
	PlayerTextDrawSetShadow(playerid, scores[playerid][1], 0);
	PlayerTextDrawSetOutline(playerid, scores[playerid][1], 0);
	PlayerTextDrawBackgroundColor(playerid, scores[playerid][1], 51);
	PlayerTextDrawFont(playerid, scores[playerid][1], 2);
	PlayerTextDrawSetProportional(playerid, scores[playerid][1], 1);
	return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
	if(type{playerid})
	{
	    score[playerid] = 0;
	    for(new i; i < 81; i++) kletka[playerid][i] = 0;
	    type{playerid} = 0;
	    hod[playerid] = false;
	    HidePanel(GetPVarInt(playerid, "SOPERNIK"));
	    SendClientMessage(GetPVarInt(playerid, "SOPERNIK"), -1, "Ваш соперник завершил игру.");
	}
	return 1;
}

public OnPlayerDeath(playerid, killerid, reason)
{
    if(type{playerid})
	{
	    score[playerid] = 0;
	    for(new i; i < 81; i++) kletka[playerid][i] = 0;
	    type{playerid} = 0;
	    hod[playerid] = false;
	    HidePanel(GetPVarInt(playerid, "SOPERNIK"));
		SendClientMessage(GetPVarInt(playerid, "SOPERNIK"), -1, "Ваш соперник завершил игру.");
	}
	return 1;
}

stock ShowPanel(playerid)
{
	for(new i; i < 81; i++)
	{
		PlayerTextDrawShow(playerid, kvadrat[playerid][i]);
		PlayerTextDrawShow(playerid, text[playerid][i]);
	}
	for(new i; i < 2; i++) TextDrawShowForPlayer(playerid, karkas[i]);
	PlayerTextDrawShow(playerid, Exit[playerid]);
	SelectTextDraw(playerid, 102);
}

stock HidePanel(playerid)
{
	type{playerid} = 0;
	hod[playerid] = false;
	DeletePVar(playerid, "SOPERNIK");

    for(new i; i < 81; i++)
	{
		PlayerTextDrawHide(playerid, kvadrat[playerid][i]);
		PlayerTextDrawHide(playerid, text[playerid][i]);
	}
	for(new i; i < 2; i++) TextDrawHideForPlayer(playerid, karkas[i]);
	PlayerTextDrawHide(playerid, Exit[playerid]);
	CancelSelectTextDraw(playerid);
	
	PlayerTextDrawHide(playerid, names[playerid][0]);
    PlayerTextDrawHide(playerid, names[playerid][1]);
    
    PlayerTextDrawHide(playerid, scores[playerid][0]);
    PlayerTextDrawHide(playerid, scores[playerid][1]);
}

stock CheckWin(playerid)
{
	new pusto;//проверка на ничью
	new chet[2];//0 - крестики, 1 - нолики
	//пробег по строкам
	for(new i, k; i < 9; i++)
	{
	    for(new j; j < 9; j++, k++)
	    {
	        if(!kletka[playerid][k])
			{
			    if(chet[0]) chet[0] = 0;//обнуляем если линия не однородна
			    if(chet[1]) chet[1] = 0;
			    pusto++;//считаем пустые клетки, если их нет и никто не выйграл, то ничья
				continue;
			}
			if(kletka[playerid][k] == 1)
			{
				chet[0]++;
				if(chet[1]) chet[1] = 0;//лучше проверим, чтобы лишний раз не выполнять 3 действия
			}
			else if(kletka[playerid][k] == 2)
			{
			    chet[1]++;
				if(chet[0]) chet[0] = 0;
			}
			if(chet[0] == 5) return PlayerWin(playerid, 1);//победа крестиков
			else if(chet[1] == 5) return PlayerWin(playerid, 2);//победа ноликов
   		}
		chet[0] = 0;//обнуляем, т.к. делаем новую итерацию
		chet[1] = 0;//-||-
	}
	//по столбцам
	for(new i, m; i < 9; i++)
	{
	    for(new j; j < 9; j++)
	    {
	        m = j*9+i;
	        if(!kletka[playerid][m])
			{
			    if(chet[0]) chet[0] = 0;
			    if(chet[1]) chet[1] = 0;
				continue;
			}
			if(kletka[playerid][m] == 1)
			{
				chet[0]++;
				if(chet[1]) chet[1] = 0;
			}
			else if(kletka[playerid][m] == 2)
			{
			    chet[1]++;
				if(chet[0]) chet[0] = 0;
			}
			if(chet[0] == 5) return PlayerWin(playerid, 1);
			else if(chet[1] == 5) return PlayerWin(playerid, 2);
	    }
	    chet[0] = 0;
		chet[1] = 0;
	}
	// проверка вдоль гл. диаг.
	for(new i, m; i < 5; i++)
	{
	    for(new j = i; j <= 8; j++)// первая часть + главная диагональ
	    {
	        m = 9*j+j-i;
	        if(!kletka[playerid][m])
			{
			    if(chet[0]) chet[0] = 0;
			    if(chet[1]) chet[1] = 0;
				continue;
			}
	        if(kletka[playerid][m] == 1)
			{
				chet[0]++;
				if(chet[1]) chet[1] = 0;
			}
			else if(kletka[playerid][m] == 2)
			{
				chet[1]++;
				if(chet[0]) chet[0] = 0;
			}
			if(chet[0] == 5) return PlayerWin(playerid, 1);
			else if(chet[1] == 5) return PlayerWin(playerid, 2);
		}
		chet[0] = 0;
		chet[1] = 0;
		if(!i) continue;// обход лишней итерации
		for(new j = 9-i-1; j >= 0; j--)// вторая часть
	    {
	        m = 9*j+j+i;
	        if(!kletka[playerid][m])
			{
			    if(chet[0]) chet[0] = 0;
			    if(chet[1]) chet[1] = 0;
				continue;
			}
	        if(kletka[playerid][m] == 1)
			{
				chet[0]++;
				if(chet[1]) chet[1] = 0;
			}
			else if(kletka[playerid][m] == 2)
			{
				chet[1]++;
				if(chet[0]) chet[0] = 0;
			}
			if(chet[0] == 5) return PlayerWin(playerid, 1);
			else if(chet[1] == 5) return PlayerWin(playerid, 2);
		}
		chet[0] = 0;
		chet[1] = 0;
	}
	// проверка вдоль побочной диагонали
	for(new i = 8, m; i >= 4; i--)
	{
	    for(new j = i; j >= 0; j--)
	    {
	        m = 9*j+i-j;
	        if(!kletka[playerid][m])
			{
			    if(chet[0]) chet[0] = 0;
			    if(chet[1]) chet[1] = 0;
				continue;
			}
	        if(kletka[playerid][m] == 1)
			{
				chet[0]++;
				if(chet[1]) chet[1] = 0;
			}
			else if(kletka[playerid][m] == 2)
			{
				chet[1]++;
				if(chet[0]) chet[0] = 0;
			}
			if(chet[0] == 5) return PlayerWin(playerid, 1);
			else if(chet[1] == 5) return PlayerWin(playerid, 2);
		}
		chet[0] = 0;
		chet[1] = 0;
		for(new j = 9-i, k; j <= 8; j++, k++)// побочная диагональ учтена выше, тут не проверяется
	    {
	        m = 9*j+8-k;
	        if(!kletka[playerid][m])
			{
			    if(chet[0]) chet[0] = 0;
			    if(chet[1]) chet[1] = 0;
				continue;
			}
	        if(kletka[playerid][m] == 1)
			{
				chet[0]++;
				if(chet[1]) chet[1] = 0;
			}
			else if(kletka[playerid][m] == 2)
			{
				chet[1]++;
				if(chet[0]) chet[0] = 0;
			}
			if(chet[0] == 5) return PlayerWin(playerid, 1);
			else if(chet[1] == 5) return PlayerWin(playerid, 2);
		}
		chet[0] = 0;
		chet[1] = 0;
	}
	if(!pusto) return PlayerWin(playerid, 3);
	return 1;
}

stock PlayerWin(playerid, idx)
{
    new playerid2 = GetPVarInt(playerid,"SOPERNIK");
	if(type{playerid} == idx)
	{
	    SendClientMessage(playerid, -1, "Вы выйграли");
		SendClientMessage(playerid2, -1, "Вы проиграли");
		score[playerid]++;
	}
	else if(type{playerid2} == idx)
	{
	    SendClientMessage(playerid2, -1, "Вы выйграли");
		SendClientMessage(playerid, -1, "Вы проиграли");
		score[playerid2]++;
	}
	if(idx == 3)
	{
        SendClientMessage(playerid2, -1, "Ничья");
		SendClientMessage(playerid, -1, "Ничья");
	}
	for(new i; i < 81; i++)
	{
		if(kletka[playerid][i])
		{
			kletka[playerid][i] = 0;
			PlayerTextDrawSetString(playerid, text[playerid][i], "_");
			PlayerTextDrawSetString(playerid2, text[playerid2][i], "_");

		    PlayerTextDrawShow(playerid, text[playerid][i]);
		    PlayerTextDrawShow(playerid2, text[playerid2][i]);
		}
	}
	UpdateScores(playerid);
 	return 1;
}

stock UpdateKletka(playerid, idx)
{
	new playerid2 = GetPVarInt(playerid,"SOPERNIK");

    new string[2];
    string = type{playerid} == 1 ? ("X") : ("O");
	PlayerTextDrawSetString(playerid, text[playerid][idx], string);
	PlayerTextDrawSetString(playerid2, text[playerid2][idx], string);

    PlayerTextDrawShow(playerid, text[playerid][idx]);
    PlayerTextDrawShow(playerid2, text[playerid2][idx]);

    kletka[playerid][idx] = type{playerid};
    kletka[playerid2][idx] = type{playerid};

	CheckWin(playerid);
}

stock UpdateScores(playerid1)
{
	new playerid2 = GetPVarInt(playerid1,"SOPERNIK");

	new string[10];
	format(string, sizeof(string), ": %02d", score[playerid1]);
	PlayerTextDrawSetString(playerid1, scores[playerid1][0], string);
	PlayerTextDrawSetString(playerid2, scores[playerid1][0], string);

    format(string, sizeof(string), ": %02d", score[playerid2]);
	PlayerTextDrawSetString(playerid1, scores[playerid1][1], string);
	PlayerTextDrawSetString(playerid2, scores[playerid1][1], string);

    PlayerTextDrawShow(playerid1, scores[playerid1][0]);
    PlayerTextDrawShow(playerid1, scores[playerid1][1]);
    PlayerTextDrawShow(playerid2, scores[playerid1][0]);
    PlayerTextDrawShow(playerid2, scores[playerid1][1]);
}

stock UpdateNames(playerid1)
{
    new playerid2 = GetPVarInt(playerid1,"SOPERNIK");

	new string[MAX_PLAYER_NAME];
	GetPlayerName(playerid1, string, MAX_PLAYER_NAME);
	format(string, sizeof(string), "%s", string);
	PlayerTextDrawSetString(playerid1, names[playerid1][0], string);
	PlayerTextDrawSetString(playerid2, names[playerid1][0], string);

	GetPlayerName(playerid2, string, MAX_PLAYER_NAME);
	format(string, sizeof(string), "%s", string);
	PlayerTextDrawSetString(playerid1, names[playerid1][1], string);
	PlayerTextDrawSetString(playerid2, names[playerid1][1], string);

	PlayerTextDrawShow(playerid1, names[playerid1][0]);
    PlayerTextDrawShow(playerid1, names[playerid1][1]);
    PlayerTextDrawShow(playerid2, names[playerid1][0]);
    PlayerTextDrawShow(playerid2, names[playerid1][1]);
}

CMD:krest(playerid, params[])
{
	if(sscanf(params, "u", params[0])) return SendClientMessage(playerid, -1, ">> /krest [id]");
	if(type{playerid}) return SendClientMessage(playerid, -1, "Вы уже играете!");
	if(!IsPlayerConnected(params[0])) return SendClientMessage(playerid, -1, "Игрока нет в сети!");
	if(playerid == params[0]) return SendClientMessage(playerid, -1, "Нельзя играть с самим собой!");
	SetPVarInt(params[0], "SOPERNIK", playerid);
 	new name[MAX_PLAYER_NAME];
 	new string[89];
 	GetPlayerName(params[0], name, MAX_PLAYER_NAME);
 	format(string, 72, "Вы предложили сыграть в крестики-нолики игроку %s", name);
 	SendClientMessage(playerid, -1, string);
	GetPlayerName(playerid, name, MAX_PLAYER_NAME);
 	format(string, sizeof(string), "%s предлагает вам сыграть в крестики-нолики\nНажмите \"Да\" для продолжения.", name);
 	ShowPlayerDialog(params[0], 1, 0, "Крестики-нолики", string, "Да", "Нет");
    return 1;
}
 
Статус
В этой теме нельзя размещать новые ответы.
Сверху Снизу