Jump to content

  • Log In with Google      Sign In   
  • Create Account

rip-off

Member Since 16 Mar 2005
Offline Last Active Today, 07:35 PM

#5174134 Dendy games copyright

Posted by rip-off on 16 August 2014 - 01:48 PM

I'd recommend against cloning a game like that. There is a grey area around any intellectual property as to whether it is so similar to be considered a derived work. You would be at risk of being sued, and whether you're actually infringing or not it can be prohibitively expensive to defend yourself against a large company.

 

Far better to write your own, unique game that you can be certain doesn't infringe, no?




#5174110 C++ Runtime Error With Odd Workaround

Posted by rip-off on 16 August 2014 - 11:28 AM

I'd recommend in future making it very clear if your example program actually demonstrates the behaviour or if it is just intended to be a simplification. I'd also recommend actually trying to make your example program exhibit the behaviour: the process of reducing the problem to the minimum conditions that reproduce it can be a very effective way of solving the problem.

 


I sort of blame VC++ for reporting the wrong line # at which the access error occurs

This is surprising. It is unclear to me how experienced you are, but regardless, are you sure you weren't a simple mistake like trying to debug a release build? I've heard of the debug database getting corrupt or out of date in older versions, maybe a clean build would have helped.

 

It might be worthwhile re-introducing such a bug and trying to get VC++ to give you the correct information, as you'll almost certainly need to investigate similar issues in future.




#5174107 Trademark question, worried

Posted by rip-off on 16 August 2014 - 11:20 AM

Disclaimer: I'm not a lawyer, and in any case laws vary from place to place.

 

As far as I understand, there are two types of trade marks, registered and unregistered. I believe you can more or less start using Any TermTM, with the addition those magical little floating letters you are now claiming an unregistered trade mark - provided you're careful not to step on an existing one!

 

I believe there are certain exemptions for trade marks in the case of something provably established prior to the trade mark.

 

The bad news is that legal disputes are expensive, and unless you're willing to do all the legal legwork yourself or find someone who will do them for free, you may have extreme difficulty paying for a defence against a big company that insists they own a certain term.

 

If you're not already familiar with them, I'd recommend researching recent cases where King were attempting to assert their Saga trade mark, and also their attempt to trade mark the term Candy.




#5174094 Looking for 'Visual' HTML/PHP editor.

Posted by rip-off on 16 August 2014 - 09:27 AM

I've no experience with using such tools, but one option to quickly make a website look better is to include something like bootstrap - though you'll probably still want to customise it eventually.




#5174086 Help with ArrayList Java

Posted by rip-off on 16 August 2014 - 08:03 AM

It sounds like you want to take the class name from a file and instantiate objects of that class type. You can do the following:

Class<?> type = Class.forName("net.gamedev.SomeMoveClass");
Move move = (Move)type.newInstance();
moves.add(move);

If you need to pass arguments, you can use the getConstructor() method and attempt to call newInstance(/* ... */) on that.

 

You may want to do some sanity checking that the class does implement or extend the Move interface / superclass.

 

That said, this smells like possibly a more complex solution than you actually need. I'd have to understand the surrounding concepts a bit more to say for sure, but I'd guess there may be other, easier ways to do this.




#5173856 Reading Files

Posted by rip-off on 15 August 2014 - 04:59 AM

In future, please don't post screenshots of code and terminal output, use copy / paste and the forum editing tools instead. As text, we can easily copy your code or output into our own system and play with it. As an image, we would have to re-type your code, which is tedious and error prone - so we probably won't. While some problems can be solved just by looking at the code and output, not all can.

 

If you find the forum editing tools a little fiddly, you can disable them and instead manually type [code][/code] around your code.

 

It will appear like so:

# Your code here!



#5173729 Best way to traverse a 2d array to dertermine the winner in Tic-Tac-Toe

Posted by rip-off on 14 August 2014 - 04:40 PM

Here is a version which, while still containing a few "magic" numbers, I think they can be more readily be deciphered than Álvaro's linked version due to the names involved. I also think the logic of the algorithm is more obvious than Álvaro's neat little trick:

enum Piece {
    None,
    X,
    O
};
 
typedef Piece Board[3][3];
 
struct VictoryCondition {
    int startIndex;
    int stride;
 
    int index(int i) const {
        return startIndex + (i * stride);
    }
};
 
const VictoryCondition possibleVictories[] = {
    {0, 1}, {3, 1}, {6, 1},
    {0, 3}, {1, 3}, {2, 3},
    {0, 4}, {2, 2}
};
 
Piece winner(Board board) {
    Piece *pointer = &board[0][0];
    for(VictoryCondition v : possibleVictories) {
        Piece possibleVictor = pointer[v.index(0)];
        if(possibleVictor != None && possibleVictor == pointer[v.index(1)] && possibleVictor == pointer[v.index(2)]) {
            return possibleVictor;
        }
    }
    return None;
}

I wouldn't say this is the "best", personally I think the tedious but obvious set of loops is probably the way to go without a compelling reason otherwise.




#5172496 Battleship in java

Posted by rip-off on 09 August 2014 - 01:37 PM

Having studied your code a bit more, there are a few more points I would make:

 

The method names like arrayAssignShip and arrayAssignInput are very mechanical, they describe what they do rather than the intent behind them. The first might be called "placeShip", the other is a little more tricky (I'll talk about this later), but in it's current state perhaps something like "mapInputToBoard". Now, play is a far better name, but it is still a bit vague. A better name might be something like "takeTurn" or "makeMove".

 

And while you've improved some of the names, the vast majority of them are unchanged. Names like the following are still very poor:

for(Ship e: playerOneShips)
    arrayAssignShip(e, playerOneBoard);
 
// ...
 
int i = 0;
int j = 0;
int k = 0;
int l = 0;
int m = 0;
int b = 0;
char c;
int inrow;
 
// ...
 

for(Ship x : playerShips)
{
    // ...
}

 

The methods you split up are still quite large. This means that they are still difficult to understand. The shortest one, arrayAssignInput, is about as long as I ideally let a method get. This way, you can see all of a method without scrolling. Shorter methods again tend to be more "obvious", and are easier to give good names as they are clearly focussed on one task.

 

You should try to separate display from your internal data structures. For example, all your arrays have 11 elements, but you're using elements 1 through 10. This is convenient as the indices you are using and the inputs you accept from the user. However, this is highly unconventional. While it isn't particularly problematic for the numeric input, it starts getting very inconvenient indeed for the character input. Instead, focus on quickly validating the user input and converting it to an internal format. In this case, the number the user inputs should be validated as between 1 and 10, and then you subtract one and use as your row index. Likewise, your character input should be validated for valid range and converted to an index, as LennyLen indicated how to do.

 

This is most obvious in the difficulty you appear to have handling the columns of the board state and the ship - by handling this as character based indexes internally, it certainly complicates a lot of things, even though it would be technically possible to achieve.

 

By elevating the concept of a "point", "location" or "co-ordinate" to something that can be described in the vocabulary of your program, 

 

Related to how you represent indices is how you represent ships and guesses. This is structuring your data in a way that is convenient for the program. There are often multiple ways to do so.

 

For instance, instead of an array of 1s and 0s (which probably should have been booleans), you can represent the board as a grid of Ship references. So if you have a patrol boat at the top left horizontally, those two occupied grid entries could point back to this Ship. This allows you to quickly get from a grid location to the Ship that cross it, so you can call methods to mark the ship as being hit.

 

In another representation, you could potentially dispense with the Ship objects themselves - all you need is something like a ShipType enumeration, with an entry for each Ship type, and an be used to get the display name and length of the ship. Your grid could consist of ShipType values of the appropriate length. Once you know a ship has been hit, you can attempt to access the adjacent horizontal or vertical entries in the grid to determine if it has been sunk.

 

Yet another way is to dispense with the grid of ship locations. Instead, your Ship class can each contain an array of booleans the length of that ship, each element of which represents whether that location has been hit. So to resolve if a hit has occurred, just iterate through the Ships, determine if the grid location lies between the locations spanned by the ship, and if so calculate the index into that array and mark it as hit.

 

Currently, you're storing redundant information - you store what you call a "count", which appears to be the number of hits that player has scored. You can also calculate this on demand by iterating though the Ships and summing the "hits taken" of each one. This isn't always a bad idea, in fact sometimes it can make sense to do so - when it might take a long time to iterate through all the elements in question. Here, it isn't going to take any time at all. However, it can cause difficulty as the values can get out of sync, though this isn't likely in your example, despite the fact that you've actually made this more complex still as you have the count arrays, and also more count variables.

 

I mentioned about your guess representation and algorithm. It is very complex. Part of the problem is that you're mapping grid co-ordinates to a separate grid, and then looping simultaneously between this array and your other arrays. Instead, try to structure the algorithm to avoid the temporary array and instead access the array of interest directly.

 

Some more general notes that are more purely stylistic:

 

I'd recommend scoping your variables much more tightly. For example, loop counters are best declared inside the loop statement, like so:

for(int i = 1; i <= 10; i++)
{
    for(int j = 1; j <= 10; j++)
    {
        if(playerGuess[i][j] == 3)
            System.out.print("* ");
        if(playerGuess[i][j] == 1)
            System.out.print("X ");
        if(playerGuess[i][j] == 0)
            System.out.print(playerGuess[i][j] + " "); 
    }
 
    System.out.print("\n");
}

 

Another example is here:

System.out.print("\nEnter a charactor from A - k for column and and number from 1 - 10 \nrespectively for the quardents of your shot: ");
c = in.next().charAt(0);
inrow  = in.nextInt();

These variables should be declared at this point, like so:

System.out.print("\nEnter a charactor from A - k for column and and number from 1 - 10 \nrespectively for the quardents of your shot: ");
char c = in.next().charAt(0);
int inrow  = in.nextInt();

 

Encapsulation is capturing logic inside a class and not having it leak outside. Ideally, all variables in all classes will be "private". Not only that, but the details of this state, even if private, should not be exposed lightly. Here is an example:

ship.setHit();
 
// ...
 
if(ship.getHit() == ship.getSize())
    System.out.print("you sunk my : " + ship.getName() + "\n");
else
    System.out.print("\n\nPlayer hit a ship\n");

Here, we can hit the "hit" value by having more meaningful method names that are not necessarily related to the variables that are used by them:

ship.markDamaged();
 
// ...
 
if(ship.isSunk())
    System.out.print("you sunk my : " + ship.getName() + "\n");
else
    System.out.print("\n\nPlayer hit a ship\n");
 
// ...
 
class Ship {
     
     private final int length;
     
     private int hitsTaken;
 
     // ...
 
     public void markDamaged() {
         assert hitsTaken < length;
         hitsTaken += 1;
     }
     
     public boolean isSunk() {
         return hitsTaken >= length;
     }
}

 

I've already mentioned about the magic numbers, but it bears repeating. It is very difficult to understand code where you see strange constants like 3 or 5 that have no meaning in an of themselves. You have to reason about the consequences before you can discover the meaning, and it can be easy to make an incorrect guess if you make a mistake or are impatient. Far better to name constants like 17 as "HitsRequiredToWin".

 

If you're only concerned about 0 or 1, using a boolean is clearer. If you're not dealing with numeric data, then consider using an enumeration.

 

I'd recommend moving your Ship class, and any other classes you make, to a separate file.




#5172147 Battleship in java

Posted by rip-off on 07 August 2014 - 04:21 PM

There are numerous issues with your current program that make it very difficult to read. The first is the variable names. Short names like "s1", "e" and "b1" are devoid of meaning. While you might know what they mean now, we don't and in a few weeks or months you won't remember either.

 

Instead, use descriptive names like playerOneFleet. You'll almost never regret using a longer word - remember a good IDE can offer you auto-completion so you won't even need to type it out fully!

 

The next issue is that your program contains lots of magic numbers. The integers in the "g" array seem to correspond with various states, but these are all implicit. Consider using named constants:

final int UNKNOWN = 0;
final int MISS = 1
final int HIT = 2;

// Later ...

if (boardPosition[y][x] == UNKNOWN) {
    if (containsShip(y, x)) {
        damageShip(y, x);
        boardPosition[y][x] = HIT;
    } else {
        boardPosition[y][x] = MISS;
    }
} else {
    System.out.println("You've already made that move!");
}

Better still would be to use an enum to represent this, but I'm not sure if you're familiar with them yet.

 

Another thing is modelling. You've modelled the Ship explicitly, but everything else is in a bunch of primitive arrays. Consider adding a class that represents the playing board itself, or perhaps two classes, one for the opponents "view" and another for the "true state" board. Try to move much of the logic into these classes.

 

Then, you should be able to cut the main() method's size in half by saying that a game consists of two player's boards - an array. You have an integer index for the active player. Each turn, you switch the active player between 0 and 1, and delegate to the appropriate object, maybe something like this:

public static void main(String args[]) {
    Board[] boards = { new Board(), new Board() };
    int activePlayer = 0;
    while (!isGameOver(boards)) {
        Board activeBoard = boards[activePlayer];
        Position position = new Position();
        while (!position.isValid()) {
            activeBoard.display();
            position = activeBoard.getMove();
        }
        activeBoard.makeMove(position);
        
        if (activePlayer == 0) {
            activePlayer = 1;
        } else {
            activePlayer = 0;
        }
    }
}




#5172143 Battleship in java

Posted by rip-off on 07 August 2014 - 03:53 PM

I believe this post should be in the coding horror forum...

Oh the horror of such a long method.

 

Your code is horribly hard to read, maybe split it up into methods to make things easier for us? wacko.png

Well, this is For Beginners, so if you're not being constructive then please don't respond at all. Presumably, the OP wouldn't be asking the question if they found this easy to do.




#5171614 Cohesion and coupling

Posted by rip-off on 05 August 2014 - 07:10 AM

Can navigation mesh building / updating be de-coupled from object creation?




#5171599 How to use mkdir in java without knowing full path

Posted by rip-off on 05 August 2014 - 04:51 AM

Searching for Java user files directory, the third result I got looks especially promising.




#5171507 Game coming out that is similar to mine: How to deal?

Posted by rip-off on 04 August 2014 - 04:14 PM

The question is: how similar?

 

For example, I had an idea about an RTS with "time travel" based mechanics. Sometime later, without implementing anything, my attention was drawn to Achron.

 

My first thoughts were: they totally made "my" game. However, on careful reading about the game and watching some of the videos, I saw they approached it from a totally different angle than I had planned. They actually appear to have implemented the ability to replay past events, whereas my idea was to have a system where you could essentially borrow resources now from your future self, but if you couldn't repay that debt within the allotted timespan, any units you built using these resources, and any damage said units did, would be undone.

 

Of course, being but an early, untested idea, it is quite possible that my version wouldn't be fun. That said, their version sounds quite complex, perhaps mine could be easier to get into and reason about strategically. I reckon the two games would feel totally different, even though they have a similar core idea.

 

For reference: since I've learned of their game I put no further thought into developing "my" version and put that energy into other ideas instead.




#5170708 Protect Against Speed hack

Posted by rip-off on 31 July 2014 - 04:04 PM

Sometimes, the best defence is less technical and more social. For example, instead of trying to solve speed hacking specifically, instead build a feature where players can vote evict an opponent who is allegedly hacking.

 

This also helps fight all forms of hacking, but with a cost of false positives.

 

As the others have mentioned, ensure you have a game good enough for someone to invest time speed hacking in before expending too much time countering it. Obviously, there is a certain bare minimum you want to do: you don't want to design a protocol that allows the client to freely teleport around the map for instance.

 

Finally, your code appears to be using way too much dynamic allocation. There is no reason to be using "new" for all those primitives - just use values. In general the amount of manual memory management in such a small amount of code worries me that overall, your game will leak memory like a sieve and you'll often end up fighting all sorts of memory corruption issues, if you aren't already.




#5170704 use of pointers

Posted by rip-off on 31 July 2014 - 03:56 PM

Here are common reasons why people use pointers:

 

0) A particular object or array is large, and they don't want to incur a copy of it when passing to a function. Passing a pointer is small (typically four or eight bytes), versus copying potentially thousands or millions of elements in an array.

 

Note: C++ provides references for this.

 

1) The programmer wishes to add an optional parameter to a function. If the parameter is not important, the programmer will pass a nullptr. Otherwise, they pass the address of an interesting object. The function can test if the pointer is null before using it.

 

2) The programmer wishes an object to live beyond the scope it is created in. Typical C++ objects live in a given scope, and can only be copied outside that scope. By dynamically allocating the object and storing a pointer to it, the original object can live longer than its scope and can be deleted later. An example in a game is a bullet, there might be a shoot() function, but the bullet should live until it hits something, not be destroyed at the end of the function.

 

Note: modern C++ recommends using smart pointers for allocating and managing the ownership of such objects.

 

3) The programmer has a rich ownership convention, where raw pointers convey the concept of "this object does not own the other object". Care must be taken with this approach to avoid dangling pointers. A possible alternative is a "weak pointer". An example in a game might be an AI object's current target.

 

4) Interacting with C style APIs. Some APIs pre-date C++, or otherwise are written in a rather simple fashion (e.g. for crossing DLL boundaries). In this case you might be forced to deal with these pointers. An example in a game might be the SDL library, which returns the "screen" surface as a raw pointer from SDL_SetVideoMode().

 

Note: Modern C++ style recommends "wrapping" the code that deals with such objects to some degree, at the very least using smart pointers to manage their lifecycle.






PARTNERS