chào mn ạ. Cho em hỏi cách giới hạn 1 con trỏ chỉ random trong 1 mảng là như nào ạ?
vd như phần in đậm của bài này ạ. E cảm ơn ạ.
Cách giới hạn 1 con trỏ chỉ random trong 1 mảng là gì?
Cách đơn giản nhất là defined ra mảng:
a[] = ["20%", "30%", "50%"];
rồi random số index trong mảng:
index = (random() % (3)); // vì mảng có 3 phần tử
rồi get ra value = a[index];
Theo mình hiểu cái đề này là đưa 2 cái nếu đó vào hàm update() chứ nhỉ. Kiểu if (T.run() + T.position < 0) T.position = 0
Vậy tỉ lệ dùng làm gì bạn
Hai tay đua đều có thể trừu tượng hóa dễ dàng fang OOP luôn.
Đúng rồi, vì rùa và thỏ chạy xác suất khác nhau nên dùng riêng hàm run kiểu oop là dễ rồi. Với lại bài này đâu có yêu cầu xài mảng xài mảng chi zậy.
dùng hàm run kiều gì ạ? em mới học lập trình thôi nên ko biết ạ. E dùng mảng để làm đường chạy cho thỏ vs rùa
Mảng là để lưu trữ (model), không phải để chạy (view) đường chạy chỉ là cái view thôi.
em mới chỉ học đến đấy thôi nên e dùng nhưng cái gì e có :v , em dùng ký tự ‘T’ để chỉ con thỏ và ‘R’ để chỉ con rùa, dùng mảng để làm đường đua bằng cách thay đổi vị trí của ‘T’ và ‘R’ trong mảng, sau đó cout mảng ra, mỗi lần random thì cout mảng 1 lần, nhưng em đang mắc cái chỗ mà khi ‘T’ và ‘R’ nhảy quá giới hạn của đường đua là 70 bước, làm cách nào để cho nó trở lại đường đua ấy. Ví dụ khi thỏ nhảy >70, thì thỏ sẽ ở vị trí đích là 70, còn khi thỏ bị trượt quá điểm xuất phát <0, thì thỏ quay trở lại vạch xuất phát ấy .
Làm dạng đồ họa à, trên Console hay Giao diện người dùng?
Vị trí của R và T chỉ cần 2 số nguyên (1 byte) là đủ.
Còn các giá trị và tỉ lệ thì ngẫu nhiên từ 1 đến tổng của các tỉ lệ (100), giá trị rơi vào phần nào thì lấy phần đó.
Trực quan:
Thay vì 100 thì mình lấy 10 cho gọn, quy ước:
- Tiến dài : A
- Tiến ngắn : B
- Trượt ngắn : X
- Trượt: Y
- Trượt dài: Z
- Ngủ: O
Theo tỉ lệ thì được:
Rùa
A: 5
B: 3
Y: 2
=>
1 2 3 4 5 6 7 8 9 10
A A A A A B B B Y Y
Thỏ
O: 2
A: 2
Z: 1
B: 3
X: 2
=>
1 2 3 4 5 6 7 8 9 10
O O A A Z B B B X X
Ngẫu nhiên từ 1 đến 10, giá trị số nằm tại đâu thì lấy giá trị hành động tương ứng.
Đúng theo khả năng xảy ra theo tỉ lệ.
Đấy là trực quan tí, viết mã thì biến tấu nó với vòng lặp, phép cộng, rand(), if
,…
Phần yêu cầu bổ sung có lẽ khá nhộn
https://en.cppreference.com/w/cpp/numeric/random/discrete_distribution xài cái này để random cho nó sành điệu
std::discrete_distribution<> rùa({50, 30, 20});
std::discrete_distribution<> thỏ({20, 20, 10, 30, 20});
hoặc
std::discrete_distribution<> rùa({.5, .3, .2});
std::discrete_distribution<> thỏ({.2, .2, .1, .3, .2});
C++11 only
Sành điệu hơn thì {Hare, Turtle}.RandomRunner is-a Runner.
chứ còn gì nữa, ko thử rand() dù chỉ 1 lần
Đúng vậy, rand()
rất gớm vì nó tiling luôn (x <- x*a mod p). XorShift64 cứ gọi là quẩy tung nóc (2.5x) vì op đơn giản.
Thỏ và Rùa là 2 object, thuộc tính là vị trí, từ 1 đến 70. Function là run/random và update. Run/random trả về int là bước nhảy. Update lấy bước nhảy đó để cho ra vị trí. Mỗi lần lặp ở main thì lại gọi hàm Thỏ.Update(). Sau mỗi lần update sẽ có thỏ với thuộc tính vị trí mới.
Đây cũng là cách người ta làm game.
Pythonista nha
#include <algorithm>
#include <ctime>
#include <iostream>
#include <random>
#include <tuple>
int main()
{
std::tuple<double, int, std::string> tortCond[]{
{.5, +3, "tiến dài"},
{.3, +1, "tiến ngắn"},
{.2, -6, "trượt"},
};
std::tuple<double, int, std::string> hareCond[]{
{.2, +0, "ngủ"},
{.2, +9, "tiến dài"},
{.1, -12, "trượt dài"},
{.3, +1, "tiến ngắn"},
{.2, -2, "trượt ngắn"},
};
const int MAX_POS = 70;
const std::string tortName = "Rùa";
const std::string hareName = "Thỏ";
int tortPos = 0;
int harePos = 0;
auto seed = time(0);
std::cout << "Seed = " << seed << "\n\n";
std::mt19937 gen(seed);
auto print = [&](const std::string& msg, bool before = true) {
std::string tortLine(MAX_POS + 1, '-');
std::string hareLine(MAX_POS + 1, '-');
tortLine[tortPos] = 'R';
hareLine[harePos] = 'T';
if (before) std::cout << msg << "\n";
std::cout << tortName << ": " << tortLine << "\n";
std::cout << hareName << ": " << hareLine << "\n";
if (!before) std::cout << msg << "\n";
std::cout << "\n";
};
auto move = [&](int& pos, const auto& cond) {
auto distribution = [&]() {
std::vector<double> prob;
std::transform(begin(cond), end(cond), std::back_inserter(prob),
[](const auto& t) { return std::get<double>(t); });
return std::discrete_distribution<>(begin(prob), end(prob));
};
return [&, dist = distribution()]() mutable {
const auto& move = cond[dist(gen)];
pos = std::clamp(pos + std::get<int>(move), 0, MAX_POS);
return std::get<std::string>(move);
};
};
auto tortMove = move(tortPos, tortCond);
auto hareMove = move(harePos, hareCond);
print("Bắt đầu!", 0);
while (tortPos < MAX_POS && harePos < MAX_POS)
print(tortName + " " + tortMove() + ", " + hareName + " " + hareMove());
if (tortPos == harePos)
std::cout << "Hòa!!!\n";
else
std::cout << (tortPos > harePos ? tortName : hareName)
<< " chiến thắng!\n";
}
edit cái lầm chỗ before = true mới đúng
Em cám ơn mọi người ạ!