I'm designing a card game and I want to follow the MVC pattern. Is the concept below fine? It's language agnostic (not written in any actual programming language).
class GameModel
{
Player p[maxPlayers];
Deck d;
Rules r;
method nextTurn()
{
p[activePlayer].makeTurn( ...some paramaters...);
...
}
method addObserver(int classID, int index, Observer o)
{
switch(classID)
{
case id_model:
this.addObserver(o);
break;
case id_deck:
d.addObserver(o);
break;
case id_player:
p[index].addObserver(o);
break;
...
}
}
}
Also, the View will need to know things like "how many cards does this player have?", shall I write (in the Model) methods like:
method cardCount(int playerNr)
{
return p[playerNr].cardCount();
}
or shall I solve this via the Observer pattern (the View would observe players and they would notify the View about the cards drawn or thrown).
Thanks in advance for your suggestions!
Caroline
Related
i have an example : player object, obstacle_1 object and obstacle_2 object. How do I check which one player collides with? I mean I want to do script_1 for colliding player with obstacle_1 and do script_2 when player collides with obstacle_2. Example:
private void OnTriggerEnter2D(Collider2D collision)
{
//script 1 when this object(player) collides with obstacle_1;
//script 2 when this object(player) collides with obstacle_2;
}
It seems like you're asking how to differentiate between objects. There are many ways of doing so, and it's hard to say which will work best for you since you didn't give a lot of context. Here are some ideas:
One of the simplest ways would be comparing the object's names:
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.name == "Obstacle_1"){
//React to obstacle 1
}
else if (collision.gameObject.name == "Obstacle_2"){
//React to obstacle 2
}
}
I really wouldn't encourage this though, since the name of the objects can be changed quite easily.
You could add Tags to obstacle_1 and obstacle_2, and compare tags, like:
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.CompareTag("Obstacle 1")){
//React to obstacle 1
}
else if (collision.gameObject.CompareTag("Obstacle 2")){
//React to obstacle 2
}
}
This is a bit better, since changing tags is not as easy as changing names, but there's still room for spelling errors. Comparing strings is not very efficient either, especially if done frequently.
You could create different components for obstacle_1 (BouncyObstacle) and obstacle_2 (SpikeObstacle), and then have your player try to get these components, like:
private void OnTriggerEnter2D(Collider2D collision) {
if(collision.gameObject.TryGetComponent(out BouncyObstacle bouncyObs){
// React to bouncy obstacle
}
else if(collision.gameObject.TryGetComponent(out SpikeObstacle spikeObs)
{
//React to spike obstacle
}
}
This is a little bit better, but every time you want to add a new obstacle, you need to add an if to your player code.
Again, it's hard to say which solution would be best. From your snippet, it seems like the player class is responsible for reacting to the obstacles, and this means that every time you want to add a new obstacle, you need to open the player class and change the OnTriggerEnter method. Perhaps it would be better to move this responsibility to separate components. That way you'll be able to add as many obstacles you want without changing any of the previous classes you made. Something like:
public class BouncyObstacle : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{
if(other.TryGetComponent(out Player player))
{
player.Bounce();
}
}
}
public class SpikeObstacle : MonoBehaviour
{
void OnTriggerEnter2D(Collider2D other)
{
if(other.TryGetComponent(out Player player))
{
player.Kill();
}
}
}
// etc..
I have the following code:
Creature::cancelWalk()
{
Player* player = getPlayer();
if (!player) {
if (getMonster() && getMonster()->getMaster() && getMonster()->getMaster()->getPlayer()) {
player = getMonster()->getMaster()->getPlayer();
}
}
if (player) {
player->sendCancelMessage(ret);
player->sendCancelWalk();
}
}
After a brief analysis, it's easy to understand I want to achieve something simple:
If the creature is the player itself, then sendCancelMessage and sendCancelWalk. Else, if the creature is a monster that also has a master that is a player, send the same stuff to the client.
Is there a better way to write this code without adding other methods on Monster, Creature and Player classes?
Monster and Player both are "siblings" deriving from Creature.
Assuming the various functions don't have different effects on multiple calls, try introducing some temporaries.
Player* player = getPlayer();
if (!player)
{
Monster monster = getMonster();
if (monster)
{
Master *master = monster->getMaster();
if (master) player = master->getPlayer()) {
}
}
if (player) {
player->sendCancelMessage(ret);
player->sendCancelWalk();
}
Beyond that, you might want to look more carefully at your design. If you have lots of nested pointers that you need to sequentially check for NULL before dereferencing, it might be worth specifying and enforcing invariants that the pointers are not NULL (which means only construct parent objects if all the component parts can be created, and never construct objects if they can only be partially constructed).
For example, if we assume that getMonster() returns non-NULL which guarantees that getMaster() and getPlayer() also don't return NULL ....
Player* player = getPlayer();
if (!player)
{
player = getMonster()->getMaster()->getPlayer());
}
if (player)
{
player->sendCancelMessage(ret);
player->sendCancelWalk();
}
I wonder if anyone can help me out. I am trying to ensure that when a manager selects his players in his team to confirm a football result, he can only choose a player once.
So my validation callback starts here:
$this->form_validation->set_rules('P1', 'The Home Team cannot play with less than 7 players', 'trim|required|callback_player1_check');
I then have this callback_function:
function callback_player1_check()
{
if ($this->fixtures_model->callback_player1_check()== TRUE)
{
$this->form_validation->set_message('P1', 'Player already selected');
return FALSE;
}
else
{
return TRUE;
}
}
This callback function then links to this model function:
function callback_player1_check() {
$player_id1 = $this->input->post('P1');
$player_id2 = $this->input->post('P2');
if ($player_id1 == $player_id2)
{
return TRUE;
}
}
So all I'm trying to do at the moment, is check if Player 1 (P1) and Player 2 (P2) are the same player. Which isn't working. If I can sort this out, I then need to check all players against each other to ensure a player is only selected once?
Any help would be great! Thanks alot.
You don't need to prefix the callback function with the word callback_
function player1_check() {
$player_id1 = $this->input->post('P1');
// etc
should do fine.
edit
See about callbacks with regards to their naming convention.
I've been developing with QT for around a week now and am pleased to say that I'm picking it up really fast. I'm an intermediate C++ programmer but picking up some parts of QT is proving to be challenging. I need to process key press events from the QPlainTextEdit when the user presses enter and I presume that the solution will involve sub classing the widget. Can any of you smart guys give me a potential implementable solution?
To really understand Qt and event handling there are two key areas of the documentation you should read. The first is the overview on The Event System and the second is a very important bit which is a cleverly hidden link on that page for QCoreApplication::notify. They should really move that to the main page of the Event System documentation as it really makes things quite clear (to me at least).
If you only need to handle some messages sent to the control - like the key-presses - there is no need to subclass it. You can alternatively use the event filtering mechanism. Here is a simple example:
Provide virtual eventFilter method in one of your QObject-based classes (e.g. the window form class).
bool MyWindow::eventFilter(QObject *watched, QEvent *event)
{
if(watched == ui->myTargetControl)
{
if(event->type() == QKeyEvent::KeyPress)
{
QKeyEvent * ke = static_cast<QKeyEvent*>(event);
if(ke->key() == Qt::Key_Return || ke->key() == Qt::Key_Enter)
{
// [...]
return true; // do not process this event further
}
}
return false; // process this event further
}
else
{
// pass the event on to the parent class
return QMainWindow::eventFilter(watched, event);
}
}
Install your class as the event filter for the target control. Form constructor is usually a good place for this code. In the following snippet this refers to the instance of class in which you implemented the eventFilter method.
ui->myTargetControl->installEventFilter(this);
i would try subclassing QPlainTextEdit and reimplementing QWidget::keyPressEvent:
void YourTextEdit::keyPressEvent ( QKeyEvent * event )
{
if( event->key() == Qt::Key_Return )
{
// optional: if the QPlainTextEdit should do its normal action
// even when the return button is pressed, uncomment the following line
// QPlainTextEdit::keyPressEvent( event )
/* do your stuff here */
event->accept();
}
else
QPlainTextEdit::keyPressEvent( event )
}
please try :
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter){
//do something
}
in your keyPressEvent() function.
Which of these 2 programming styles do you prefer? Why? Are there particular advantages to one over the other?
// Style 1
if (doBorder)
doTheBorder();
if (doFrame)
doTheFrame();
if (doDraw)
doTheDraw();
void doTheBorder()
{
// ...
}
void doTheFrame()
{
// ...
}
void doTheDraw()
{
// ...
}
// Style 2
doTheBorder();
doTheFrame();
doTheDraw();
void doTheBorder()
{
if (!doBorder)
return;
// ...
}
void doTheFrame()
{
if (!doFrame)
return;
// ...
}
void doTheDraw()
{
if (!doDraw)
return;
// ...
}
The first. The second seems to be... lacking in confidence. Why call doTheBorder() if you don't even know if you want the border to be done? IMO, you should assert that the border really needs doing, and then call doTheBorder() with confidence!
...Also, from a more technical point of view: if doTheBorder() is in a closed API, a developer in the distant future might call it and if the second style is employed, they may wonder why the border didn't get done, despite their call to doTheBorder(). Of course, sometimes certain circumstances or restrictions or limitations may dictate that the second style be used, but I'd avoid it when possible.