7/03/2014

AI 3.1 - XÁC SUẤT NGẪU NHIÊN



  3.1 - Xác Suất Ngẫu Nhiên -

Trong phần bài viết AI 3.* này, chúng ta sẽ cùng tìm hiểu cách vận dụng xác suất vào game. Người làm game thường thêm các yếu tố xác suất hoặc các mẫu hội thoại vào các nhân vật AI, điều đó khiến hệ thống trí tuệ nhân tạo không thể đoán trước được giúp người chơi cảm thấy thích thú hơn hay có thêm những kinh nghiệm thử thách khác nhau.

Hãy lấy một ví dụ gần gũi nhất đó là game đá bóng cơ bản, cầu thủ có thể sút bóng tự do nếu như có cầu thủ bị phạm lỗi khi đang cố gắng dẫn bóng sang phía đối phương. Vì vậy, nếu thay vì lúc nào cũng cho phạm lỗi và cho sút bóng tự do thì người lập trình có thể áp dụng xác suất để chỉ có 98% cơ hội bị phạm lỗi và sút tự do mà thôi. Vậy nếu như 2% còn lại xảy ra, nghĩa là bạn phạm lỗi mà bị cho qua (không phạt) thì người chơi sẽ có những cảm xúc phản hồi tình huống trên ngay lập tức. Sẽ có người rất tức giận và thất vọng hỏi tại sao lại không phạt, trong khi người phạm lỗi lại cảm thấy may mắn và mất vía.

Qua đó, chúng ta sẽ thấy việc áp dụng xác suất sẽ làm cho game chúng ta trở nên sinh động và thực tế hơn, tránh cho game việc cứ lặp đi lặp lại vài hành động.

Trong bài viết đầu tiên về xác suất ngẫu nhiên này, chúng ta sẽ cùng làm một game gieo xúc sắc đơn giản.


Sự Ngẫu Nhiên

Xác suất giống như điều kiện trong thực tế hoặc những kết quả thường hay xảy ra. Khi nói đến xác suất, không thể bỏ qua tính quan trọng của tính ngẫu nhiên. Sự Phát Sinh Những Con Số Ngẫu nhiên (Random Number Generation - RNG) là việc rất quan trọng khi cần tạo ra kết quả không đoán trước được. Kĩ thuật đơn giản và dễ hiểu nhất để mô phỏng quá trình này chính là việc gieo xúc sắc với việc phát sinh ngẫu nhiên giá trị từ 1 đến 5. Những con số ngẫu nhiên được tạo ra bằng máy tính bởi Trình Tạo Giả Số Ngẫu Nhiên (Pseudorandom Number Generator - PRNG) và những con số được xác định giống với dãy số ngẫu nhiên dựa trên giái trị hạt giống ban đầu. Vậy, nếu chúng ta biết chứng minh giá trị hạt giống, chúng ta có thể tái tạo những chuỗi số ngẫu nhiên lại. Khi đó, chúng không chỉ còn là ngẫu nhiên thật sự nữa. Giá trị hạt giống thường được tái tạo từ trạng thái của hệ thống máy tính, như thời gian đã trôi qua phần triệu giây khi máy tính bắt đầu xử lý. Một vài RNG thì mang tính ngẫu nhiên hơn những cái khác. Nếu chúng ta tạo ra một chương trình mã hóa, chúng ta có thể xem xét kĩ sự ngẫu nhiên hơn của RNG. Bây giờ hãy cũng tạo một game để xem cách chúng ta tạo ra những con số ngẫu nhiên với Unity3D.


Lớp Random

Script trong Unity3D có một lớp Ranodm để tạo ra dữ liệu ngẫu nhiên. Hai thuộc tính  sử dụng hầu hết sẽ là seed và value.

static var seed : int

Seed ở đây là để lưu kết quả vừa được phát sinh để tránh lần sau lại phát sinh trùng. Thông thường, chúng ta không muốn giá trị của seed cứ lặp đi lặp lại, vì khi đó chương trình của chúng ta sẽ dễ đoán ra được kết quả. Mục đích khác để lưu giá trị seed là để kiểm tra chương trình.

static var value : float

Bạn có thể tham khảo thuộc tính của phương thức Random.value là lấy giá trị ngẫu nhiên trong miền giá trị [0.0 ; 1.0]. Cả hai giá trị 0.0 và 1.0 đều có thể được trả về bởi thuộc tính của phương thức này. Một phương thức khác cũng tương tự là Range.

static function Range (min : float, max : float) : float

Phương thức này sẽ lấy giá trị ngẫu nhiên từ miền giá trị. Khi đặt miền giá trị là kiểu số nguyên Int, phương thức này sẽ lấy ngẫu nhiên giá trị trong miền giá trị [min ; max). Nghĩa là giá trị nhỏ nhất vẫn được trả về trong khi giá trị lớn nhất thì không. Còn nếu đặt miền giá trị là kiểu số thực Float thì miền giá trị sẽ được lấy là [min ; max], khi đó cả min lẫn max đều có thể được trả về.

Tạo game xúc sắc đơn giản

Bây giờ chúng ta sẽ tạo một game Đổ xúc sắc đơn giản với các số nút được tạo một cách ngẫu nhiên giữa 1 đến 6. Người chơi sẽ thắng dựa theo số nút người chơi dự đoán và nhập vào khung Input so với số nút kết quả được gieo.

B1. Tạo Scene mới với tên SimpleDiceGame bằng cách vào File | New Project. Điều chỉnh đường dẫn thư mục chứa Project và nhấn nút Create.


B2. Tại thẻ Project, nhấp chọn nút Create | C# Script và đặt tên là DiceGame.


B3. Double click vào file này và chèn đoạn code sau vào:

using UnityEngine;
using System.Collections;

public class DiceGame : MonoBehaviour {
    public string inputValue = "1";

    void OnGUI() {
        GUI.Label(new Rect (10, 10, 100, 20), "Input: ");
        inputValue = GUI.TextField(new Rect(120, 10, 50, 20), inputValue, 25);
        if (GUI.Button(new Rect(100,50,50,30),"Play")) {
            Debug.Log("Throwing dice...");
            Debug.Log("Finding random between 1 to 6...");
            int diceResult = Random.Range(1,7);
            Debug.Log("Result: " + diceResult);
            if (diceResult == int.Parse(inputValue)) {
                guiText.text = "DICE RESULT: " + diceResult.ToString() + "\r\nYOU WIN!";
            }
            else {
                guiText.text = "DICE RESULT: " + diceResult.ToString() + "\r\nYOU LOSE!";
            }
        }
    }
}


B4. Tại thẻ Hierarchy, nhấp chọn Create | GUI Text và kéo thả file C# DiceGame ở thẻ Project vào GUI Text vừa tạo ở thẻ Hierarch.


Đây là một game ví dụ sử dụng yếu tố ngẫu nhiên, dĩ nhiên nó không có trường hợp phát sinh. Mỗi mặt của xúc sắc đều có cùng cơ hội được chọn.

2 comments:

  1. Mình nghĩ ad nên post kèm hình ảnh để mem còn đối xứng kết quả

    ReplyDelete