I. Mở đầu

Đúng như tiêu đề bài viết này, mình sẽ xây dựng trò chơi Kéo Búa Bao đơn giản mà sẽ không dùng tới hàm if, switch…case hay là biểu thức tam phân nào cả. Vậy không dùng các hàm trên, thì xây dựng bằng cách nào? Để trả lời cho câu hỏi trên, mình sẽ đưa ra một ví dụ như sau:

Đây là luật chơi của trò Kéo Búa Bao:

Luật chơiKéoBúaBao
KéoHòaThuaThắng
BúaThắngHòaThua
BaoThuaThắngHòa
Bảng 1. Bảng luật chơi của trò Kéo Búa Bao.

Từ bảng luật chơi bên trên, mình sẽ tạo 1 mảng 2 chiều như sau:

Chỉ số dòng và cột012
0HòaThuaThắng
1ThắngHòaThua
2ThuaThắngHòa
Bảng 2.

Mình sẽ gọi nó là mảng A.

Theo như cái bảng thể hiện mảng 2 chiều bên trên, thì mình sẽ quy ước như sau:

  • Chỉ số dòng và cột bằng 0: Kéo.
  • Chỉ số dòng và cột bằng 1: Búa.
  • Chỉ số dòng và cột bằng 2: Bao.
  • Các chỉ số dòng sẽ đại diện cho người chơi.
  • Các chỉ số cột sẽ đậi diện cho máy.

Tiếp theo, mình sẽ xây dựng 1 phương thức để tạo ngẫu nhiên 1 số nằm trong dãy 0 <= X <= 2. Đây sẽ là lựa chọn của máy tính. Còn đối với lựa chọn của người chơi, mình sẽ làm giao diện có thêm các lựa chọn để nhấn vào, các lựa chọn này cũng có giá trị nằm trong dãy 0 <= X <= 2.

Như vậy, công việc còn lại bây giờ đó là xử lý kết quả trò chơi, mình sẽ làm như sau:

Mình sẽ lấy ra phần tử của mảng 2 chiều, bằng cách lấy lựa chọn của người chơi đưa chỉ số dòng, lấy lựa chọn của máy đưa vào chỉ số cột.

Ví dụ:

  • A[0][1]: Người chơi chọn kéo (0), máy chọn búa (1) => Lấy phần tử dòng 0 cột 1, kết quả là thua (có thể xem lại bảng 1bảng 2 ở bên trên để dễ hình dung).
  • A[2][1]: Người chơi chọn bao (2), máy chọn búa (1) => Lấy phần tử dòng 2 cột 1, kết quả là thắng.

Như vậy là các bạn đã hiểu được cách để xây dựng trò chơi Kéo Búa Bao mà không cần dùng tới câu lệnh if, switch case, biểu thức tam phân phải không nào?

II. Viết chương trình

1. Chuẩn bị

Như tiêu đề thì các bạn đã biết là mình sẽ dùng C# để viết trò chơi này, cụ thể mình sẽ tạo 1 project Windows Form App (.NET Framework) trên Visual Studio 2019.

Về phiên bản .NET Framework và Visual Studio thì các bạn có thể chọn cái nào mà bạn thích cũng được, không nhất định là phải giống với mình.

2. Thêm hình ảnh

Vì trong trò chơi mình có sử dụng giao diện, chính vì thế phải có hình ảnh để thể hiện cho sinh động.

Mình sẽ dựng giao diện trò chơi Kéo Búa Bao đơn giản như sau:

Trước tiên, các bạn phải thêm các hình này vào (tải và lưu vào 1 thư mục bất kỳ):

Trong Solution Explorer => Nhấn đúp vào Resources.resx:

Sau khi Resources.resx đã hiện lên => Nhấn vào Add Resource => Add Existing File…:

3. Tạo Form và xây dựng giao diện

Tạo Form: Theo mặc định khi tạo 1 project Windows Form App thì đã có sẵn 1 form rồi, bạn có thể dùng nó cũng được. Còn nếu bạn muốn tạo 1 form mới, hãy tìm trên Google, những kiến thức về phần này có rất nhiều trên Google.

Giao diện gồm:

  • 3 Label.
  • 1 RichTextBox.
  • 5 PictureBox (Các PictureBox sẽ hiển thị các hình ảnh mà mình đã thêm vào).
Giao diện của trò chơi Kéo Búa Bao.

Đặt tên và tên biến cho các toolbox:

Mình sẽ dùng các số được đánh ở hình trên để nhắc đến các toolbox ở những phần sau của bài viết.

*Cách thêm ảnh vào PictureBox:

Nhấn vào PictureBox => tại cửa sổ Properties (có thể mở bằng cách nhấn vào PictureBox => chuột phải, chọn Properties).

Nhấn vào thuộc tính Image, sau đó nhấn tiếp vào dấu 3 chấm:

Chọn hình và nhấn OK.

4. Chuyển đến phần code xử lý

Khi đã làm xong các bước trên, mình sẽ tiến hành viết code vào trong phần file code xử lý.

Xem tiếp tại:

  • II/5. Tạo mảng hai chiều.
  • II/6. Tạo mảng một chiều chứa các hình ảnh.
  • II/7. Tạo một biến đếm.
  • II/8. Xây dựng các phương thức.

*Cách để vào phần file code xử lý:

– Cách 1: Nhấn chuột phải vào form, chọn View Code.

– Cách 2: Nhấn phím tắt F7 (bạn đang ở màn hình có chứa form).

5. Tạo mảng hai chiều

Từ bảng 2 ở bên trên, mình xây dựng 1 mảng 2 chiều như sau:

private string[,] bangKetQua = new string[,] {
            { "Hòa", "Thua", "Thắng" },
            { "Thắng", "Hòa", "Thua" },
            { "Thua", "Thắng", "Hòa" }
};

6. Tạo mảng một chiều chứa các hình ảnh

private Bitmap[] dsHinhAnh = new Bitmap[] {
  global::KeoBuaBao.Properties.Resources.Keo,
  global::KeoBuaBao.Properties.Resources.Bua,
  global::KeoBuaBao.Properties.Resources.Bao,
};

7. Tạo một biến đếm

Đây là phần không cần thiết, vì thế các bạn có thể bỏ qua.

private int count;

Tại phương thức khởi tạo, mình sẽ bổ sung dòng gán biến count = 1.

public frmMain()
{
  InitializeComponent();
  count = 1;
}

8. Xây dựng các phương thức

Phương thức “int TaoLuaChonCuaMayTinh()“: Sử dụng phương thức Next(int minValue, int maxValue) của lớp Random để tạo ra số ngẫu nhiên từ 0 => 2.

Trong phương thức Next(int minValue, int maxValue) mình có đưa vào 2 tham số với giá trị là 0 và 3, nó tương đương minValue = 0, maxValue = 3. Về phương thức Next(int minValue, int maxValue) sẽ tạo ra số ngẫu nhiên theo nguyên tắc sau: minValue <= X < maxValue (0 <= X < 3).

private int TaoLuaChonCuaMayTinh()
{
  Random random = new Random();
  return random.Next(0, 3); // 0 <= X < 3
}

Phương thức “string LayKetQua(int luaChon1, int luaChon2)“: Phương thức này sẽ lấy ra giá trị phần tử của mảng 2 chiều thông qua chỉ số dòng và cột được đưa vào.

private string LayKetQua(int luaChon1, int luaChon2)
{
  return bangKetQua[luaChon1, luaChon2];
}

Phương thức “void Choi(int luaChonCuaNguoiChoi)“:

– Đầu tiên, lấy ra lựa chọn của máy tính lưu vào 1 biến.

– Thay đổi hình cho đúng với lựa chọn của máy và người chơi (0 = Kéo, 1 = Búa, 2 = Bao).

– Gọi phương thức “string LayKetQua(int luaChon1, int luaChon2)” đưa vào cho tham số luaChon1luaChonCuaNguoiChoi, luaChon2luaChonCuaMayTinh. Sau đó đưa kết quả vào lbResult để hiển thị nó lên màn hình.

rtxtResult (RichTextBox): Sẽ hiện thị số lượt chơi (có thể bỏ qua, mình đã trình bày tại phần II/7. Tạo một biến đếm ở bên trên), kết quả nếu đứng ở phía máy (Gọi phương thức “string LayKetQua(int luaChon1, int luaChon2), đưa vào cho tham số luaChon1luaChonCuaMayTinh, luaChon2luaChonCuaNguoiChoi) và kết quả nếu đứng ở phía người chơi.

private void Choi(int luaChonCuaNguoiChoi)
{
  int luaChonCuaMayTinh = TaoLuaChonCuaMayTinh();
  pbComputer.Image = dsHinhAnh[luaChonCuaMayTinh];
  pbPlayer.Image = dsHinhAnh[luaChonCuaNguoiChoi];
  lbResult.Text = LayKetQua(luaChonCuaNguoiChoi, luaChonCuaMayTinh);
  rtxtResult.Text = $"Lượt chơi thứ: {count++}\n\n" +
    $"Máy: {LayKetQua(luaChonCuaMayTinh, luaChonCuaNguoiChoi)}\n" +
    $"Bạn: {lbResult.Text}";
}

9. Thêm sự kiện click cho các PictureBox

Mình sẽ thêm 3 sự kiện click cho các PictureBox có đánh số thứ tự 7, 8, 9 (Xem lại tại phần II/3. Tạo Form và xây dựng giao diện).

Đối với pbPlayer_Keo với sự kiện pbPlayer_Keo_Click, pbPlayer_Bua với sự kiện pbPlayer_Bua_Click, pbPlayer_Bao với sự kiện pbPlayer_Bao_Click, mình sẽ đều gọi phương thức “void Choi(int luaChonCuaNguoiChoi)” với tham số luaChonCuaNguoiChoi có giá trị như sau:

  • pbPlayer_Keo_Click: luaChonCuaNguoiChoi = 0.
  • pbPlayer_Bua_Click: luaChonCuaNguoiChoi = 1.
  • pbPlayer_Bao_Click: luaChonCuaNguoiChoi = 2.
private void pbPlayer_Keo_Click(object sender, EventArgs e)
{
  Choi(0);
}

private void pbPlayer_Bua_Click(object sender, EventArgs e)
{
  Choi(1);
}

private void pbPlayer_Bao_Click(object sender, EventArgs e)
{
  Choi(2);
}

Về cách thêm sự kiện, nếu các bạn không biết cách làm thì có thể tìm trên Google, có rất nhiều bài viết hướng dẫn về nó.

10. Hoàn thiện chương trình

Phần code xử lý:

using System;
using System.Drawing;
using System.Windows.Forms;

namespace KeoBuaBao
{
    public partial class frmMain : Form
    {
        private int count;

        private Bitmap[] dsHinhAnh = new Bitmap[]{
            global::KeoBuaBao.Properties.Resources.Keo,
            global::KeoBuaBao.Properties.Resources.Bua,
            global::KeoBuaBao.Properties.Resources.Bao,
        };

        /// <summary>
        /// index của hàng 0 = Kéo, 1 = Búa, 2 = Bao, áp dụng tương tự cho chỉ số cột.
        /// 
        /// </summary>
        private string[,] bangKetQua = new string[,]{
            { "Hòa", "Thua", "Thắng" },
            { "Thắng", "Hòa", "Thua" },
            { "Thua", "Thắng", "Hòa" }
        };

        public frmMain()
        {
            InitializeComponent();
            count = 1;
        }

        private void frmMain_Load(object sender, EventArgs e)
        {

        }

        private int TaoLuaChonCuaMayTinh()
        {
            Random random = new Random();
            return random.Next(0, 3); // 0 <= X < 3
        }

        private string LayKetQua(int luaChon1, int luaChon2)
        {
            return bangKetQua[luaChon1, luaChon2];
        }

        private void Choi(int luaChonCuaNguoiChoi)
        {
            int luaChonCuaMayTinh = TaoLuaChonCuaMayTinh();
            pbComputer.Image = dsHinhAnh[luaChonCuaMayTinh];
            pbPlayer.Image = dsHinhAnh[luaChonCuaNguoiChoi];
            lbResult.Text = LayKetQua(luaChonCuaNguoiChoi, luaChonCuaMayTinh);
            rtxtResult.Text = $"Lượt chơi thứ: {count++}\n\n" +
                $"Máy: {LayKetQua(luaChonCuaMayTinh, luaChonCuaNguoiChoi)}\n" +
                $"Bạn: {lbResult.Text}";
        }

        private void pbPlayer_Keo_Click(object sender, EventArgs e)
        {
            Choi(0);
        }

        private void pbPlayer_Bua_Click(object sender, EventArgs e)
        {
            Choi(1);
        }

        private void pbPlayer_Bao_Click(object sender, EventArgs e)
        {
            Choi(2);
        }
    }
}

Phần code giao diện:

namespace KeoBuaBao
{
    partial class frmMain
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.lbComputer = new System.Windows.Forms.Label();
            this.lbPlayer = new System.Windows.Forms.Label();
            this.pbComputer = new System.Windows.Forms.PictureBox();
            this.pbPlayer = new System.Windows.Forms.PictureBox();
            this.lbResult = new System.Windows.Forms.Label();
            this.pbPlayer_Keo = new System.Windows.Forms.PictureBox();
            this.pbPlayer_Bua = new System.Windows.Forms.PictureBox();
            this.pbPlayer_Bao = new System.Windows.Forms.PictureBox();
            this.rtxtResult = new System.Windows.Forms.RichTextBox();
            ((System.ComponentModel.ISupportInitialize)(this.pbComputer)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbPlayer)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbPlayer_Keo)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbPlayer_Bua)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbPlayer_Bao)).BeginInit();
            this.SuspendLayout();
            // 
            // lbComputer
            // 
            this.lbComputer.AutoSize = true;
            this.lbComputer.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lbComputer.ForeColor = System.Drawing.Color.Red;
            this.lbComputer.Location = new System.Drawing.Point(12, 42);
            this.lbComputer.Name = "lbComputer";
            this.lbComputer.Size = new System.Drawing.Size(79, 36);
            this.lbComputer.TabIndex = 0;
            this.lbComputer.Text = "Máy:";
            // 
            // lbPlayer
            // 
            this.lbPlayer.AutoSize = true;
            this.lbPlayer.Font = new System.Drawing.Font("Microsoft Sans Serif", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lbPlayer.ForeColor = System.Drawing.Color.Red;
            this.lbPlayer.Location = new System.Drawing.Point(12, 461);
            this.lbPlayer.Name = "lbPlayer";
            this.lbPlayer.Size = new System.Drawing.Size(167, 36);
            this.lbPlayer.TabIndex = 1;
            this.lbPlayer.Text = "Người chơi:";
            // 
            // pbComputer
            // 
            this.pbComputer.Image = global::KeoBuaBao.Properties.Resources.Bua;
            this.pbComputer.Location = new System.Drawing.Point(230, 12);
            this.pbComputer.Name = "pbComputer";
            this.pbComputer.Size = new System.Drawing.Size(185, 121);
            this.pbComputer.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
            this.pbComputer.TabIndex = 2;
            this.pbComputer.TabStop = false;
            // 
            // pbPlayer
            // 
            this.pbPlayer.Image = global::KeoBuaBao.Properties.Resources.Bua;
            this.pbPlayer.Location = new System.Drawing.Point(230, 408);
            this.pbPlayer.Name = "pbPlayer";
            this.pbPlayer.Size = new System.Drawing.Size(185, 121);
            this.pbPlayer.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
            this.pbPlayer.TabIndex = 3;
            this.pbPlayer.TabStop = false;
            // 
            // lbResult
            // 
            this.lbResult.Font = new System.Drawing.Font("Arial", 48F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lbResult.ForeColor = System.Drawing.Color.Olive;
            this.lbResult.Location = new System.Drawing.Point(164, 214);
            this.lbResult.Name = "lbResult";
            this.lbResult.Size = new System.Drawing.Size(366, 92);
            this.lbResult.TabIndex = 4;
            this.lbResult.Text = "HÒA";
            this.lbResult.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
            // 
            // pbPlayer_Keo
            // 
            this.pbPlayer_Keo.Image = global::KeoBuaBao.Properties.Resources.Keo;
            this.pbPlayer_Keo.Location = new System.Drawing.Point(131, 572);
            this.pbPlayer_Keo.Name = "pbPlayer_Keo";
            this.pbPlayer_Keo.Size = new System.Drawing.Size(96, 71);
            this.pbPlayer_Keo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
            this.pbPlayer_Keo.TabIndex = 6;
            this.pbPlayer_Keo.TabStop = false;
            this.pbPlayer_Keo.Click += new System.EventHandler(this.pbPlayer_Keo_Click);
            // 
            // pbPlayer_Bua
            // 
            this.pbPlayer_Bua.Image = global::KeoBuaBao.Properties.Resources.Bua;
            this.pbPlayer_Bua.Location = new System.Drawing.Point(274, 572);
            this.pbPlayer_Bua.Name = "pbPlayer_Bua";
            this.pbPlayer_Bua.Size = new System.Drawing.Size(96, 71);
            this.pbPlayer_Bua.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
            this.pbPlayer_Bua.TabIndex = 7;
            this.pbPlayer_Bua.TabStop = false;
            this.pbPlayer_Bua.Click += new System.EventHandler(this.pbPlayer_Bua_Click);
            // 
            // pbPlayer_Bao
            // 
            this.pbPlayer_Bao.Image = global::KeoBuaBao.Properties.Resources.Bao;
            this.pbPlayer_Bao.Location = new System.Drawing.Point(422, 572);
            this.pbPlayer_Bao.Name = "pbPlayer_Bao";
            this.pbPlayer_Bao.Size = new System.Drawing.Size(96, 71);
            this.pbPlayer_Bao.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
            this.pbPlayer_Bao.TabIndex = 8;
            this.pbPlayer_Bao.TabStop = false;
            this.pbPlayer_Bao.Click += new System.EventHandler(this.pbPlayer_Bao_Click);
            // 
            // rtxtResult
            // 
            this.rtxtResult.Location = new System.Drawing.Point(18, 147);
            this.rtxtResult.Name = "rtxtResult";
            this.rtxtResult.Size = new System.Drawing.Size(140, 240);
            this.rtxtResult.TabIndex = 9;
            this.rtxtResult.Text = "";
            // 
            // frmMain
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(557, 655);
            this.Controls.Add(this.rtxtResult);
            this.Controls.Add(this.pbPlayer_Bao);
            this.Controls.Add(this.pbPlayer_Bua);
            this.Controls.Add(this.pbPlayer_Keo);
            this.Controls.Add(this.lbResult);
            this.Controls.Add(this.pbPlayer);
            this.Controls.Add(this.pbComputer);
            this.Controls.Add(this.lbPlayer);
            this.Controls.Add(this.lbComputer);
            this.Name = "frmMain";
            this.Text = "Kéo Búa Bao";
            this.Load += new System.EventHandler(this.frmMain_Load);
            ((System.ComponentModel.ISupportInitialize)(this.pbComputer)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbPlayer)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbPlayer_Keo)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbPlayer_Bua)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pbPlayer_Bao)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.Label lbComputer;
        private System.Windows.Forms.Label lbPlayer;
        private System.Windows.Forms.PictureBox pbComputer;
        private System.Windows.Forms.PictureBox pbPlayer;
        private System.Windows.Forms.Label lbResult;
        private System.Windows.Forms.PictureBox pbPlayer_Keo;
        private System.Windows.Forms.PictureBox pbPlayer_Bua;
        private System.Windows.Forms.PictureBox pbPlayer_Bao;
        private System.Windows.Forms.RichTextBox rtxtResult;
    }
}

III. Chạy chương trình

IV. Source code

Tải xuống tại đây:

V. Lời kết

Như vậy, thông qua bài viết này mình đã chia sẻ cho các bạn cách xây dựng trò chơi Kéo Búa Bao mà không cần dùng đến câu lệnh if, switch case, biểu thức tam phân. Mình đã vận dụng mảng 2 chiều, chỉ số dòng, cột của mảng 2 chiều để giải quyết bài toán trên. Cuối cùng, cảm ơn các bạn đã đọc bài viết, nếu các bạn có vấn đề cần giải đáp, hãy để lại bình luận cho mình nhé!

Categorized in:

Tagged in:

,