Форум программистов, компьютерный форум, киберфорум
C# Windows Forms
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.54/35: Рейтинг темы: голосов - 35, средняя оценка - 4.54
2 / 2 / 0
Регистрация: 16.01.2014
Сообщений: 24

Как продумать логику игры компьютера в крестики-нолики

16.01.2014, 18:33. Показов 6810. Ответов 22
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть такая заготовка под крестики-нолики.... В общем, синтаксис и основы знаю, но не понимаю, что, куда, зачем и как.... Создал массив кнопок, теперь вот как все это привязать к действиям? как самому установить значение, как организовать, чтобы комп сам делал ход....

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
using System;
using System.Windows.Forms;
using System.Drawing;
 
 
namespace second // пространство имен просто от балды
{
     class MyForm : Form // класс от объекта форма
    {
      public   MyForm () // метод - конструктор
         {
             
             int m = 10;
            int  n = 10;
         
              Button[,] Buttons = new Button[n,m];//создаю массив кнопок
             
             for (int i = 0; i < n; i++ )
                 for (int j = 0; j < m; j++)
                 {
                     Buttons[i, j] = new Button();//создание кнопки
                     Buttons[i, j].Size = new Size(40, 40);//размер кнопы
                     Buttons[i, j].Location = new Point(5 + j * 40, 5 + i * 40);//координаты кнопок
                                                        //где 5 отступ от формы I*30 координата кнопы
                  Buttons[i, j].Name = Convert.ToString(i) + " " + Convert.ToString(j);//даю кнопе имя состоящие из i пробел j
                     //вызываю функцию для конкретной щелкнутой кнопы в массиве
                     Buttons[i, j].BackColor = Color.Black;//фон кнопы белый
                     this.Controls.Add(Buttons[i, j]);//Пихаем кнопу на форму
                    Buttons[i, j].MouseClick +=MyForm_MouseClick;
               
                    
                 }
          
          
         }
 
 
        
 
         void MyForm_MouseClick(object sender, MouseEventArgs e)
         {
             
         }
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
16.01.2014, 18:33
Ответы с готовыми решениями:

Крестики-Нолики: как запрограммировать логику игры
я новичок в программировании, нужно написать игру Крестики-Нолики, таблица и форма вроде готовы, осталось самое сложное, сама игра:( пока...

Крестики нолики - как организовать интерфейс и логику игры?
С чего нужно начать в коде ? Если хочу в Windows Forms сделать. Как создать массив это я знаю, а как этому массиву добавить квадратики...

Сохранение и открытие игры крестики - нолики
Здравствуйте, хотелось бы реализовать открытие сохраненной ранее игры из текстового файла. Массив и переменные сохраняются по разным...

22
154 / 153 / 29
Регистрация: 21.05.2010
Сообщений: 338
16.01.2014, 18:44
kabernet1971, google подскажет даже самые извращённые примеры реализации игры "крестики нолики" на C#...
1
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
16.01.2014, 18:50
Автор, зачем всё делать с нуля? Создай в Visual Studio заготовку под Windows-приложение и размещай там свои кнопки в графическом режиме сколько влезет (по крайней мере, для 9 кнопок это не проблема). И с событиями удобнее работать, чем писать всё вручную.

А вообще - прочитай любой учебник по C# для чайников и все подобные вопросы отпадут.
1
2 / 2 / 0
Регистрация: 16.01.2014
Сообщений: 24
16.01.2014, 19:13  [ТС]
Да я понял, что можно и так и сяк.... я ни как не вкурю, как конкретно реализовать например такой ход - чтобы в моем событии, которое отзывается на нажатие на любую кнопку в массиве, что то происходило, кроме ShowMessage... т.е. как в это самое событие, по нажатию на кнопку, впихать нужн ое мне действо?? просто... но ни черта не могу понять...

Добавлено через 26 секунд
Блин... это ж форум для начинающих...

Добавлено через 15 секунд
я ж не просто так спрашиваю
0
814 / 422 / 169
Регистрация: 08.02.2013
Сообщений: 711
16.01.2014, 19:44
Зачем тебе массив если он локальный и лямбд не видно?
Чтобы много не переписывать, вот простой пример как сохранить данные в кнопке (координаты), как прочесть значение Крестик/Нолик, как получить кнопку при нажатии на нее:
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
 
namespace TicTacToe
{
    public partial class Form1 : Form
    {
        const int m = 10, n = 10;
        Button[,] Buttons = new Button[n, m];
 
        public Form1()
        {
            InitializeComponent();
            
            for (int i = 0; i < n; i++)
                for (int j = 0; j < m; j++)
                {
                    Buttons[i, j] = new Button()
                    {
                        Size = new Size(40, 40),  
                        Location = new Point(5 + j * 40, 5 + i * 40), 
                        BackColor = Color.White,
                        Tag = new Point(i, j) // запоминаем координаты, чтобы быстро искать в массиве
                    };
                    this.Controls.Add(Buttons[i, j]);
                    Buttons[i, j].Click += ButtonClick;
                }
        }
 
        void ButtonClick(object sender, EventArgs e)
        {
            Button b = sender as Button; // Получили кнопку
            Point p = (Point)b.Tag; // Получили координаты
 
            if (b.Text == String.Empty) // Можно нажимать только на пустую
            {
                b.Text = "x"; // Поменяли текст
 
                // Ход компьютера: поиск пустой кнопки и установка О
                foreach (Button f in Buttons)
                {
                    if (f.Text == String.Empty)
                    {
                        f.Text = "o";
                        break;
                    }
                }
            }
        }
    }
}
1
2 / 2 / 0
Регистрация: 16.01.2014
Сообщений: 24
17.01.2014, 15:07  [ТС]
Попробую разобраться, что к чему... Спасибо большое....

Добавлено через 3 часа 36 минут
Вот эту строку не понял
C#
1
Point p = (Point)b.Tag;
, в остальном вроде разобрался. Это "явное приведение" к нужному типу? правильно понимаю?
я почему-то думал, что надо слепить массив из кнопок (неважно, программно, или прям на форме), а потом второй массив, такой же, как кнопки, только целыми числами, и потом уже реализовывать перебор и прочее, при нажатии на "новая" (в смысле "новая игра"), массив заполняется нулями, а один игрок делает 1, а второй -1. А потом все это привязывать к нажатию кнопок. А в этом вот случае, получается надо будет перебирать "х" и "о"... не совсем догоняю, как это делать... в случае с цифрами можно как-то сумму к числу 3 свести, вот и выигрыш, а с "иксами" что делать? они же не складываются? или я опять что-то не понимаю... Извиняюсь заранее, понимаю, что тема может быть уже разжевана миллион раз, но "Гугл в помощь" ни катит... Я не смог найти подробностей, кроме как здесь.... думал, что смогу сам разобраться, но к счастью не смог

Добавлено через 1 час 23 минуты
Еще не понял, как можно получить координаты из Point ?
0
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
17.01.2014, 17:08
Цитата Сообщение от kabernet1971 Посмотреть сообщение
Вот эту строку не понял
C#
1
Point p = (Point)b.Tag;
Это "явное приведение" к нужному типу? правильно понимаю?
Да. В Tag хранится значение типа Object, а нам нужно привести его к Point.
Цитата Сообщение от kabernet1971 Посмотреть сообщение
Еще не понял, как можно получить координаты из Point ?
Координата по х хранится в Point.X, а по у - в Point.Y. То есть в следующем коде:
C#
1
2
3
4
...
int x = p.X;
int y = p.Y;
...
мы получим координаты в виде "чистых" целых чисел, но это не к чему, так как можно сразу напрямую обращаться p.X и p.Y.

Цитата Сообщение от kabernet1971 Посмотреть сообщение
А в этом вот случае, получается надо будет перебирать "х" и "о"... не совсем догоняю, как это делать... в случае с цифрами можно как-то сумму к числу 3 свести, вот и выигрыш, а с "иксами" что делать? они же не складываются? или я опять что-то не понимаю...
Это же элементарно - просто сверить количество "х" или "о" в строке/столбце/диагонали. Допустим у тебя есть массив кнопок Button[] btnArray, который состоит из 9 кнопок и тебе надо проверить, есть ли ряд "х" или "о". Подумав логически, определяем, что количество возможных "зачеркиваний" равна 8 (3 по столбцам, 3 по строкам и 2 по диагоналям). Ну а затем сверяем текст 0, 1, 2 кнопки, затем 3, 4, 5 кнопки и т.д. Если текст на них совпает, значит там ряд одинаковых символов и игрок ходивший этим символом победил.

[/CSHARP]
1
2 / 2 / 0
Регистрация: 16.01.2014
Сообщений: 24
17.01.2014, 17:52  [ТС]
тут у меня нагромождение из 100 кнопок, так что все ряды просматривать будет наверное затруднительно... но об этом я пока еще не думал... у меня проблема, что при выполнении моей программы, крестики ставлю, где хочу, а нули рисует строго по порядку, от верхнего угла... я так понимаю, что массив просматривается по порядку, так и заполняет, где находит пустую кнопку, а вот как сделать, чтобы комп лепил свою ерудну по-умному....
0
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
17.01.2014, 18:35
Цитата Сообщение от kabernet1971 Посмотреть сообщение
а вот как сделать, чтобы комп лепил свою ерудну по-умному....
Вот, держи мои крестики-нолики. Компьютер ходит случайно. Посмотри код - я его детально прокомментировал.
Вложения
Тип файла: zip TicTacToe.zip (55.5 Кб, 94 просмотров)
2
2 / 2 / 0
Регистрация: 16.01.2014
Сообщений: 24
17.01.2014, 18:39  [ТС]
Спасибо, буду разбираться....
0
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
17.01.2014, 18:40
Цитата Сообщение от kabernet1971 Посмотреть сообщение
тут у меня нагромождение из 100 кнопок, так что все ряды просматривать будет наверное затруднительно...
Это можно сделать более компактно с помощью циклов.
Цитата Сообщение от kabernet1971 Посмотреть сообщение
чтобы комп лепил свою ерудну по-умному....
Надо писать свой АИ, а это уже совсем другая история.

Как-то я не обратил внимания, что у тебя крестики-нолики не 3х3... Хотя бы маленькие для начала сделал.
0
2 / 2 / 0
Регистрация: 16.01.2014
Сообщений: 24
18.01.2014, 16:05  [ТС]
А что такое АИ ? ))
0
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
18.01.2014, 17:18
Цитата Сообщение от kabernet1971 Посмотреть сообщение
А что такое АИ ? ))
AI - Artificial Intelligence, искусственный интеллект или по простому - ИИ
0
2 / 2 / 0
Регистрация: 16.01.2014
Сообщений: 24
19.01.2014, 11:54  [ТС]
вот я разобрался в твоей вещи, но понял, что в ней комп ходит случайным образом, т.е. при помощи функции random, а я думаю, как сделать перебор более продуманным... не врублюсь, по какому принципу перебирать кнопки? случайным образом, тогда неинтересно играть.... а вот по другому... в общем, с синтаксисом я разберусь, но вот принцип не могу вкурить...
0
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
19.01.2014, 13:51
kabernet1971, проблема в том, что ты слишком высоко замахнулся. В этом случае надо использовать теорию принятия решений и на основе какого-то с критериев выбора создавать интеллектуальную систему, которая и будет подыскивать оптимальные ходы для компьютера. Лично у меня подобная программа преподавалась на предпоследнем и последнем курсах университета и я сомневаюсь, что ты сможешь во всем так вот нахрапом разобраться.

Вот статья, думаю она будет тебе полезной.
0
2 / 2 / 0
Регистрация: 16.01.2014
Сообщений: 24
19.01.2014, 14:44  [ТС]
Да уж, а я то думал, что все будет проще... ))) не хотел же ведь так глубоко... просто циклами, что-то вроде, если сумма больше 2, то тогда -1, чтобы уменьшить, или что то подобное... Т.е. ветвления, которые основаны на простых математических действиях, а не там, где комп должен воплощать "зло" ))) ладно, пойду дальше "курить"... может что проясниться ))))
0
814 / 422 / 169
Регистрация: 08.02.2013
Сообщений: 711
19.01.2014, 19:26
kabernet1971, попробуй стандартные 3*3 написать, там вроде не сложно, а реализации интересные можно придумать.
0
2 / 2 / 0
Регистрация: 16.01.2014
Сообщений: 24
24.01.2014, 08:48  [ТС]
С самого начала была такая задумка, размер массива меняется только изменением цифр при загрузке приложения.... Я не пойму, как перейти к ходу компа... мне подсказали код, где в foreach в массиве кнопок ставится "0" в первом же батоне, где b.text пустой, а мне непонятно, как перейти к перебору именно кнопок не по тексту, а по расположению... блин, даже объяснить не могу )))
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
void MyForm_MouseClick(object sender, MouseEventArgs e)
        {
            Button b = sender as Button; // Получили кнопку
            Point p = (Point)b.Tag; // Получили координаты
 
            if (b.Text == String.Empty) // Можно нажимать только на пустую
            {
                b.Text = "X"; // Поменяли текст
 
                foreach (Button f in Buttons)
                
              
                    if (f.Text==String.Empty) //тут вот ставится отметка, где "ходит комп"
                   
                    {
                        
                        /* 
                         * Point fp = (Point)f.Tag; // вот тут я пытаюсь как-то привязатся к координатам, но ни черта не могу )))
                fp.X = p.X + 1;
               fp.Y = p.Y+1;
                         * */
                f.Text = "O";
                    break;
                         
                
                }
            }
в общем, собрал в голове мысли, попытаюсь сформулировать....
я так понимаю, что мне не обязательно пытаться перебирать кнопки в foreach, а можно сразу же обозначать какую-нибудь кнопку нулем, одновременно с нажатием кнопки пользователем... т.е. если какой-то баттон нажали мышкой, одновременно с этим ставить рядом ход компа, но вот тут и возникает проблема, как поставить "ход компа" в кнопку рядом?? или тут вообще проблема в другом...
0
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
24.01.2014, 15:04
Цитата Сообщение от kabernet1971 Посмотреть сообщение
но вот тут и возникает проблема, как поставить "ход компа" в кнопку рядом??
Скажем так - идея насчет хранения координат кнопки в Tag усложняет взаимодействие с кнопками (такое чувство, что тот, кто тебе это посоветовал сделать, решил подшутить над тобой). Для того чтобы получить кнопку с какими-то конкретными необходимыми координатами, нам нужно перебирать все кнопки и сверять их Tag'и с необходимыми нам координатами, предварительно приведя их к типу Point... Слишком много ненужных действий, которые кроме того тратят лишнюю память и процессорное время. Советую отказаться от этой идеи в пользу игры. И забыть, как страшный сон, перебирание кнопок ненужным в данном случае foreach'ем. По этому расскажу как сделать подобное, имея двумерный массив кнопок, в котором первое измерение указывает координату кнопки по X, а второе - координату кнопки по Y.

Итак...

Допустим, что ты походил на клетку с координатами playerX и playerY. Массив кнопок - btnArray[,]. Соответственно, кнопки, которые находятся рядом с той, на которую походил игрок, это:
C#
1
2
3
4
5
6
7
8
btnArray[playerX - 1, playerY - 1]
btnArray[playerX, playerY - 1]
btnArray[playerX + 1, playerY - 1]
btnArray[playerX - 1, playerY]
btnArray[playerX + 1, playerY]
btnArray[playerX - 1, playerY + 1]
btnArray[playerX, playerY + 1]
btnArray[playerX + 1, playerY + 1]
То есть 8 кнопок вокруг. Естественно, игрок может походить на краях поля, то есть количество кнопок будет меньше восьми, по этому надо проверять, чтобы в выражениях выше, к примеру, playerX - 1 было больше или равно нулю, а playerY + 1 было меньше или равно высоте игрового поля и т.д.

Добавлено через 52 минуты
Однако, если присвоить обработку события MouseClick массиву кнопок, просто по аргументу sender довольно сложно определить координаты нажатой кнопки. По этому, как для определения координат нажатой кнопки, Tag всё таки годится.
1
Си-решеточник
 Аватар для Rameron
141 / 135 / 60
Регистрация: 07.02.2011
Сообщений: 669
24.01.2014, 15:39
От нечего делать, тоже решил набросать такие крестики-нолики. В прикрепленном файле компьютер ходит на случайную соседнюю клетку от той, на которую походил игрок. Если таковой нет, то компьютер ходит на абсолютно случайную клетку. Проверки на победу пока не делал, также не делал проверки на полную заполненность поля.

Если хочешь - посмотри. Код не комментировал, но по названиям переменных и функций можно понять, что, где и как.
Вложения
Тип файла: zip BigTicTacToe.zip (55.0 Кб, 30 просмотров)
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.01.2014, 15:39
Помогаю со студенческими работами здесь

Дописать Крестики-нолики для игры с ботом
Пишу игру Крестики - Нолики взял за основу код зарубежного человека, написал что бы игра была самим с собой. Помогите как сделать что бы...

Более правильный алгоритм ходов компьютера в игре крестики-нолики
Не так давно я захотел сделать крестики нолики. Вчера наконец-то появилось время и я их сделал. Скорее-всего код ужасен, но я знаю совсем...

Крестики-нолики, общие принципы реализации игры
привет помогите реализовать игру с комьютером в крестиках ноликах на с# ! вот примерный код using System; using...

Проверка подключения к Интернету - продумать логику поведения программы
Здравствуйте. Пишу код, который каждые 3 секунды проверяет подключение к интернету. Проблема в том, что когда интернета нет, ничего не...

Как реализовать крестики-нолики 3х3 на button-ах
как сделать игру между двумя игроками чтобы можно было выбирать кто первым ходит,условые для вывода выиграша,и выбор новой игры ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Работа со звуком через SDL3_mixer
8Observer8 08.02.2026
Содержание блога Пошагово создадим проект для загрузки звукового файла и воспроизведения звука с помощью библиотеки SDL3_mixer. Звук будет воспроизводиться по клику мышки по холсту на Desktop и по. . .
SDL3 для Web (WebAssembly): Основы отладки веб-приложений на SDL3 по USB и Wi-Fi, запущенных в браузере мобильных устройств
8Observer8 07.02.2026
Содержание блога Браузер Chrome имеет средства для отладки мобильных веб-приложений по USB. В этой пошаговой инструкции ограничимся работой с консолью. Вывод в консоль - это часть процесса. . .
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru