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ơi | Kéo | Búa | Bao |
Kéo | Hòa | Thua | Thắng |
Búa | Thắng | Hòa | Thua |
Bao | Thua | Thắng | Hòa |
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ột | 0 | 1 | 2 |
0 | Hòa | Thua | Thắng |
1 | Thắng | Hòa | Thua |
2 | Thua | Thắng | Hòa |
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 1 và bả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).
Đặ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ố luaChon1 là luaChonCuaNguoiChoi, luaChon2 là luaChonCuaMayTinh. 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ố luaChon1 là luaChonCuaMayTinh, luaChon2 là luaChonCuaNguoiChoi) 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é!
biết là c# câu lệnh có hơi dài dòng nhưng ngôn ngữ này lại có chứng nay vô cùng mạnh mẽ đặc biệt về đồ họa. bt là khó nhưng đành cũng phải học thôi tạm bt python thôi