Игрушка
Запись от Lisishkas размещена 02.08.2019 в 23:13
Показов 1981
Комментарии 4
|
Всем доброго времени суток, решил опробовать блогерство. Так вот, стоя ехал в общественном транспорте, смотрел как чудак режется в игру какую-то. Потом вспомнил через время об этой игре и решил узнать насколько такая игра увлекательна. Написал свой вариант, чисто "для себя" и по мотивам. Ради спортивного интереса. Назвал её "nums". Как играть: стрелками влево-вправо-вверх-вниз(или клавишами ASDE) сдвигаете все числа к стенке поля(нажали вверх - значит к верхней и т.д.). Если два одинаковых числа встречаются - они суммируются. Тип того. Выложу исходник, писалось по-быстрячку и "для себя" - я уже когда "нарезался", потом чуть-чуть поправил код и дописал немного комментариев - вдруг кто-то заюсает и будет счастлив. Что нужно для сборки: язык C#, NF ~3.5. Создаем проект, в нем "грохаем" файлы сгенерированные для Form, открываем Program.cs, вставляем туда код и запускаем. Примерно так. [CSHARP]using System; using System.Collections.Generic; using System.Windows.Forms; using System.Drawing; using System.Runtime.Serialization.Formatters.Binary; using System.IO; namespace nums { partial class Program : Form { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Program()); } static int H = 4, // клеток 4х4 S = 60; // сторона клетки в пикселах int CH = SystemInformation.CaptionHeight + 10; // высота заголовка формы + отступ int FBS = SystemInformation.FrameBorderSize.Width; // ширина границы формы Random rand = new Random(); int[,] map; // массив значений в клетках int score; // очки int[] nums = {2, 4, 8}; // появляющиеся числа int start_nums_count = 3; // количество чисел вначале Font font = new Font("Times", 18); [Serializable] public class record // класс рекорда { public int score; // очки public DateTime dt = DateTime.Now; // время public record(int score) { this.score = score; } } List<record> records = new List<record>(); // рекорды int max_records = 10; // максимально сохранять рекордов string file_name = Application.StartupPath + "/rec.bin"; // файл для сохранения рекордов Program() { InitializeComponent(); this.Text = "nums"; this.FormBorderStyle = FormBorderStyle.FixedDialog; this.StartPosition = FormStartPosition.CenterScreen; this.MaximizeBox = false; this.DoubleBuffered = true; this.ClientSize = new Size(2 * FBS + H * S, FBS + CH + H * S); this.Paint += new PaintEventHandler(Program_Paint); this.KeyUp += new KeyEventHandler(Program_KeyUp); Init(); LoadRecords(); } void Init() { map = new int[H, H]; AddNum(start_nums_count); score = 0; } void AddNum(int count) { for (int i = 0; i < count; i++) { int j = H * H * 10; do { int x = rand.Next(H); int y = rand.Next(H); if (map[x, y] == 0) { map[x, y] = nums[rand.Next(0, nums.Length)]; break; } }while (j-->0); } } void Program_KeyUp(object sender, KeyEventArgs e) { switch (e.KeyData) { case Keys.Up: case Keys.W: for (int z = 0; z < H; z++) for (int i = 0; i < H; i++) { for (int j = 1; j < H; j++) { if (map[i, j - 1] == 0) { map[i, j - 1] = map[i, j]; map[i, j] = 0; } else if (map[i, j - 1] == map[i, j]) { score += map[i, j]; map[i, j - 1] <<= 1; map[i, j] = 0; } } Foo(); } break; case Keys.Right: case Keys.D: for (int z = 0; z < H; z++) for (int j = 0; j < H; j++) { for (int i = H - 2; i >= 0; i--) { if (map[i + 1, j] == 0) { map[i + 1, j] = map[i, j]; map[i, j] = 0; } else if (map[i + 1, j] == map[i, j]) { score += map[i, j]; map[i + 1, j] <<= 1; map[i, j] = 0; } } Foo(); } break; case Keys.Down: case Keys.S: for (int z = 0; z < H; z++) for (int i = 0; i < H; i++) { for (int j = H - 2; j >= 0; j--) { if (map[i, j + 1] == 0) { map[i, j + 1] = map[i, j]; map[i, j] = 0; } else if (map[i, j + 1] == map[i, j]) { score += map[i, j]; map[i, j + 1] <<= 1; map[i, j] = 0; } } Foo(); } break; case Keys.Left: case Keys.A: for (int z = 0; z < H; z++) for (int j = 0; j < H; j++) { for (int i = 1; i < H; i++) { if (map[i - 1, j] == 0) { map[i - 1, j] = map[i, j]; map[i, j] = 0; } else if (map[i - 1, j] == map[i, j]) { score += map[i, j]; map[i - 1, j] <<= 1; map[i, j] = 0; } } Foo(); } break; case Keys.Escape: this.Close(); break; case Keys.F1: ShowRecords(); break; default: return; } AddNum(1); Invalidate(); if (IsEnd()) { AddAndSaveRecords(score); ShowRecords(); Init(); Invalidate(); } } bool IsEnd() { //пустые поля for (int i = 0; i < H; i++) for (int j = 0; j < H; j++) if (map[i, j] == 0) return false; //рядом одинаковые for (int i = 0; i < H; i++) for (int j = 1; j < H; j++) if (map[i, j - 1] == map[i, j]) return false; for (int i = 1; i < H; i++) for (int j = 0; j < H; j++) if (map[i - 1, j] == map[i, j]) return false; return true; } void Foo() { //здесь может будет логика отрисовки System.Threading.Thread.Sleep(5 / H); // при больших H закомментировать Invalidate(); Application.DoEvents(); } void AddAndSaveRecords(int score) { records.Add(new record(score)); records.Sort(delegate(record r1, record r2) { return r2.score.CompareTo(r1.score); }); if (records.Count > max_records) records.RemoveRange(max_records, records.Count - max_records); using (Stream stream = new FileStream(file_name, FileMode.Create, FileAccess.Write, FileShare.None)) new BinaryFormatter().Serialize(stream, records); } void LoadRecords() { if (File.Exists(file_name)) { using (Stream stream = new FileStream(file_name, FileMode.Open, FileAccess.Read, FileShare.None)) records = (List<record>)new BinaryFormatter().Deserialize(stream); } } void ShowRecords() { string str = "Вы набрали " + score.ToString() + " очков"; if (records.Count > 0) { str += "\n\r\n\rТаблица рекордов:"; for (int i = 0; i < records.Count; i++) { str += "\n\r" + records[i].score.ToString() + "\t" + records[i].dt.ToString("dd-MM-yyyy HH:mm"); } } MessageBox.Show(str); } void Program_Paint(object sender, PaintEventArgs e) { // сетка for(int i = 0; i <= H; i++) e.Graphics.DrawLine(new Pen(Color.Black), FBS + i * S, CH, FBS + i * S, CH + H * S); for (int j = 0; j <= H; j++) e.Graphics.DrawLine(new Pen(Color.Black), FBS, CH + j * S, FBS + H * S, CH + j * S); // числа for (int i = 0; i < H; i++) for (int j = 0; j < H; j++) if (map[i, j] != 0) { SizeF sf = e.Graphics.MeasureString(map[i, j].ToString(), font); e.Graphics.DrawString(map[i, j].ToString(), font, Brushes.Blue , FBS + i * S + (S - sf.Width) / 2, CH + j * S + (S - sf.Height) / 2); } // очки e.Graphics.DrawString("Очки - " + score.ToString(), font, Brushes.Blue, FBS, 0); } private void InitializeComponent() { this.SuspendLayout(); // // Program // this.ResumeLayout(false); } } }[/CSHARP] Только сильно не критикуйте(можно мягко и действительно в тему что и как "не то"), ОК? |
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 4
Комментарии
-
Запись от SoftIce размещена 03.08.2019 в 06:14
-
Спасибо что разъяснил.
Тогда моя реализация отличается от 2048, и\или имеет свои особенности и плюшки:
1) Нет таймера - сколько угодно можно думать над ходом.(отвлекли - через время вернулся и продолжил)
2) Практически равновероятно появляются 2, 4, 8.(Не тестил, но думаю легко можно сделать только 2 и 4). Можно хоть и 1,3,7 сделать - такое тестил.
3) Параметром H меняется размер поля: H=4 - значит 4х4, 10 - значит 10х10. (Понравились "блицы" 2х2 и 3х3).
4) За один ход собираются, например, 4-2-2-8 в 16, хоть влево хоть вправо.
5) "Если при нажатии кнопки местоположение плиток или их номинал не изменится, то ход не совершается." - а смысл? Тогда можно жамкать одну кнопку и новые числа не будут появляться.
Запускал на исполнение?
[B]SoftIce[/B],
Как код и стиль программирования, потянет? Я просто программист-одиночка и один на предприятии, коллег программистов нет(1С-ники есть, но...).
Есть смысл продолжать блоггерство?
Например, для решатора яп. кроссвордов еще один блок нужно прописать, чтоб решал и 5-го уровня. 1-4 решает норм. Нужно добавить еще один алгоритм. Когда добавлю, выложить?Запись от Lisishkas размещена 03.08.2019 в 17:08
-
Да, запускал.
Смысл в том, что если на поле ничего не изменилось, то не должны фишки появляться. Я вот запустил, пару раз промахнулся мимо клавиши, нажал не туда, и на поле появилось 4 лишние плитки, что совсем не добавляет интереса к игре, а вызывает раздражение и недоумение.
Извините, написал с точки зрения обычного пользователя.Запись от SoftIce размещена 04.08.2019 в 17:31
-
[QUOTE=SoftIce;bt22249]Да, запускал.
Смысл в том, что если на поле ничего не изменилось, то не должны фишки появляться. Я вот запустил, пару раз промахнулся мимо клавиши, нажал не туда, и на поле появилось 4 лишние плитки, что совсем не добавляет интереса к игре, а вызывает раздражение и недоумение.
Извините, написал с точки зрения обычного пользователя.[/QUOTE]
Спасибо за тест.
[QUOTE=SoftIce;bt22249]Смысл в том, что если на поле ничего не изменилось, то не должны фишки появляться.[/QUOTE]
Если все фишки стоят возле правой границы и ты не хочешь, менять их расположение - логично для появления новой фишки нажать "->". И новые фишки появляются, да.
Еще раз напомню, это не Бест-версия в продакшн, написано ради спортивного интереса.
Попробую пофиксить, если пойму прикол. Я здесь поставил себе лимит - уложиться в 300 строк.
И вообще это кроме типа NDA по работе - просто баловство(Если интересуетесь не с точки зрения простого юзера). Ну, тип того :).
А как "код" - читаемый? Не говнокодище часом? Вот здесь хотелось бы вашу рецензию.Запись от Lisishkas размещена 16.08.2019 в 21:33


