I was following this tutorial (https://academy.realm.io/posts/eric-maxwell-mvc-mvp-and-mvvm-on-android/) implementing different patterns (MVC, MVP and MVVM) in Kotlin for a Tic Tac Toe game. At the MVVM part, the example does the following:
public class TicTacToeViewModel implements ViewModel {
private Board model;
public final ObservableArrayMap<String, String> cells = new ObservableArrayMap<>();
public final ObservableField<String> winner = new ObservableField<>();
public TicTacToeViewModel() {
model = new Board();
}
[...]
public void onClickedCellAt(int row, int col) {
Player playerThatMoved = model.mark(row, col);
cells.put("" + row + col, playerThatMoved == null ?
null : playerThatMoved.toString());
winner.set(model.getWinner() == null ? null : model.getWinner().toString());
}
[...]
}
Considering that the model, of class Board, already has an attribute board (that is an Array < Array < Cell > >), what's the point for replicate that board with other variable at the TicTacToeViewModel? Is not possible refer to the model board directly with an LiveData or Observable class? Same for the winner
I've saw as well many implementations on Github doing the same, and I am wondering if that's happening due to heritance of the article or in fact has to be this way when the data is kind of complex (a 2D array in this particular case)
I'll appreciate any comments or thoughts on this. Thanks in advance!
I skimmed the tutorial and the github page, and in short I would recommend not following that tutorial :)
Looking at the source code on github, it's clearly an unfinished project. For example, the one layout in the entire project just has a "Hello, world!" TextView in it, which is boilerplate code you get just for creating an Android project...
But to answer your question in a more general sense, you don't necessarily need redundant data structures to represent the board. One reason you might want them is to differentiate between what is displayed to the user versus what the app uses to track the state of the game. For example, the user sees 'O's and 'X's, but perhaps your ViewModel or backing data structure tracks the board as a binary string for the sake of memory and performance (imagine scaling the game out to a much larger board.) But you could probably just create a function to convert the underlying data to a user-friendly format for display, without the need for redundant data structures.
Related
This question is about Couchbase lite (no Sync Gateway).
I'm new to Couchbase, I managed to use the demo app, but I don't understand it completely.
It contains this code which (as far as I understand, since I'm not native English speaker) retrieve views to populate a listview with the indexes:
// This code can be found in ListsActivity.java
// in the setupViewAndQuery() method
com.couchbase.lite.View listsView = mDatabase.getView("list/listsByName");
if (listsView.getMap() == null) {
listsView.setMap(new Mapper() {
#Override
public void map(Map<String, Object> document, Emitter emitter) {
String type = (String) document.get("type");
if ("task-list".equals(type)) {
emitter.emit(document.get("name"), null);
}
}
}, "1.0");
}
listsLiveQuery = listsView.createQuery().toLiveQuery();
Could anyone give me a hand with what each part is doing?
In which step is the listview populated
Can I change "list/listsByName" in the code (line 3)? What would happen?
Can I emit more than one element?
The code is a little bit convoluted. Let's answer the easy parts first.
Can I change "list/listsByName" in the code (line 3)?
Yes. That's just the name of the Couchbase View. You choose the View name. Unfortunately the terms used in Couchbase and Android overlap some. A Couchbase View is a kind of static index of your database.
Can I emit more than one element?
Yes. You can emit most anything you want. Take a look at the documentation here
Now, tracing how the Android ListView gets updated:
In ListsActivity.java notice in the onCreate method a ListAdapter instance gets added to the ListView. This ListAdapter is a private inner class that extends LiveQueryAdapter.
LiveQueryAdapter is in the utils subpackage. If you look at its constructor, you'll see it adds a change listener to the query passed in. When triggered, this change listener sets an enumerator equal to the rows passed back by the live query, then calls notifyDataSetChanged to tell the list to refresh itself. That, in turn, causes getView in ListAdapter to get called. That's where the data is pulled from the database and used to populate a list entry.
I'm writing an application for iOS and Android in parallell and I am facing a small problem.
I am displaying a list of settings to the user and the settings data is internally represented in settings for section, like this:
Section
Section object
Section object
Section
Section object
etc.
In iOS, when the user clicks a setting object, or when the system wants to paint the view for it, it calls a method with an NSIndexPath object. For example:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
and the sections are handled automatically.
In Android, the listviews are "flattened", lacking better terminology. So that a method is called only with a row index:
public Object getItem(int position);
Now it is actually a quite hard problem to solve trying to represet sections directly in the Adapter (MySettingsAdapter extends BaseAdapter).
Right now this problem is solved by flattening the entire underlaying data structure, but it's a lot of duplicated code for almost nothing. The nicer solution I can think of is to do something like the following in my MySettingsAdapter:
class MySettingsAdapter extends BaseAdapter {
MyInternalDataStructure settingsData;
int sections;
int rowsForSection[sections];
public MySettingsAdapter (MyInternalDataStructure settingsData) {
this.settingsData = settingsData;
this.sections = settingsData.sections;
for (int i = 0; i < sections; i++) {
rowsForSection[i] = settingsData.settingsInSection[i].size();
}
}
#Override
public Object getItem(int position) {
int sectionFromPostion;
int rowFromPosition;
// Calculate section and row here...
return settingsData.getSetting(sectionFromPostion, rowFromPosition);
}
}
And I just can't get the calculations for sectionFromPostion and rowFromPostion right...
Unfortunately Android does not have quite the same ability in regards to sections as you can achieve with the UITableView. However Android does provide a solution, the ExpandableListView. While similar to a ListView it works a bit differently and interacts with a different type of adapter.
Android provides the SimpleExpandableListAdapter that you can use with the ExpandableListView. I'll warn you now. It's clunky and pretty restricting. Additionally, it requires you to organize your data into a List of Maps which in itself can be a pain to do.
Alternatively, you can create your own adapter for the ExpandableListView by implementing the BaseExpandableListAdapter. It's very similar to implementing the BaseAdapter. It just has a few extra bells and whistles to support a tier like structure.
Basically all these Expandable...[foo] classes introduce the idea of having a group (the section) and children (the data under a section). Instead of having an index to the data in your adapter, you'll have a groupPosition and a childPosition. Meanwhile the ExpandableListView has this sorta murky middle notion of positions as it works with group/child positions, packed positions, and flattened positions.
As a side note. Depending on how your data is organized, I'd suggest checking out the Rolodex Adapters found in this 3rd party library. They are meant to make working with ExpandableListViews easier and has plenty of code examples and a demo app to help get you going.
Firstly, thanks for your time.
How do I use Box2D Sensors on the EdgeShape(s) to determine a collision condition with the Ball, then use said condition to increment a score variable?
I am creating a Pong clone using Box2D via libGDX! I have found great examples and tutorials from iforce2d and Ray Wenderlich, however, they are written in languages and libraries that I am not familiar with at the moment. Trying to comprehend and convert the code is not working for me. If code or a link to a Java/libGDX rendition of Sensor use could be provided, I would be much obliged.
I am receiving contacts in my code, but I do not yet understand the recipe for the algorithm that would ignore contact with the paddle rectangles and arena boundary, but increment a score variable upon collision with the left or right EdgdeShape sensors.
I have scavenged the web for two weeks in an effort to find bits and pieces of useful information to hack together a solution before posting to SO, however, I am officially stumped on this one. I could use some guidance.
i don't know how far you came with your efforts and never worked with libgdx, but the way to go is something like this:
fixture.setUserData() (could be body) to recognize the single bodies you have (outLeft, outRight, paddleLeft, paddleRight, ball) - this could be any useful information from Integers to the whole game object instance, what ever you need
set your left/right boundaries as sensor fixture.setSensor(true) - afaik this has to be set to not let the boundaries induct a collision
implement your contact listeners endContact(Contact contact) (or begin contact, like you want it) call and request the fixtures A and B from the contact object with contact.getFixtureA/B() and determine if the given collision is relevant for your needs e.g.:
-
public void endContact(Contact contact) {
Fixture fixtureA = contact.getFixtureA();
Fixture fixtureB = contact.getFixtureB();
Object userDataA = fixtureA.getBody().getUserData();
Object userDataB = fixtureB.getBody().getUserData();
// check if one is ball
if (userDataA instanceof Ball) {
checkBallCollision(userDataB);
} else if (userDataB instanceof Ball) {
checkBallCollision(userDataA);
}
}
private void checkBallCollision(Object userData) {
if (userData instanceof outLeft) {
//add points to right player
} else if (userData instanceof outRight) {
//add points to left player
}
}
-4. add your ContactListener to your World.setContactListener()
as said, i'm not 100% sure that this will work, never used it in libgdx, just some smaller experiments with andengines box2d extension, but in fact it should be the same for both engines. here is another link handling sensors in andengine: http://www.matim-dev.com/creating-sensors.html
Basically, I need to add items to the arraylist. Am I correct in using a separate class (this is in part what I am practicing here) or is that a stupid idea because it is basically just an arraylist. I thought I would create a class because I want to randomise additions to it, etc. Alternately, since it is just an arraylist class, should I use "extends arraylist" or something similar??? Code examples most welcome. I am obviously missing some crucial programming theory here. Thank you.
NOTE I have removed what I think is unrelated code
I have a main:
public class cgame2 extends Activity {
private ArrayList<Integer> cToChooseFromImages; // clear image list
colourlist colourlistused = new colourlist();
colourlist userscolourlist = new colourlist();
....truncated....towards the end of my code I have......
colourlistused.randomaddnewitem();
And I have a class (called colourlist):
import java.util.ArrayList;
import java.util.Random;
import android.util.Log;
public class colourlist {
private ArrayList<Integer> clist;
private int picked;
int imagetodisp;
public colourlist() {
}
public void randomaddnewitem() {
Random randomtouse = new Random(System.nanoTime());
picked = randomtouse.nextInt(3);
clist.add(picked); // this is where the program crashes according to log info
}
public void addnewitem(int itemtoadd) {
clist.add(itemtoadd);
}
.....etc.....
If you're adding functionality to ArrayList, the best way is just the way you have done it.
Create a member ArrayList of your class and create functions to extend the behavior. This is called Composition.
Contrast with Inheritance, or creating a subclass of ArrayList, which can create more problems by unnecessarily coupling your implementation to ArrayList.
Don't forget to initialize the list. The best way would be:
List<Integer> clist = new ArrayList<Integer>();
Use the interface List to make your code more flexible if you choose to change the specific list implementation later.
Creating a class for your array list isn't a bad idea, classes in and of themselves are data structures, and this will allow to manipulate the data easier. By having the array list in it's own class, you will be able to get it, set it, send it, alter it, etc, with ease. However, when it comes to creating classes, you generally want to create classes that could be considered objects. If you are a beginning programmer, I would recommend exploring and researching object oriented analysis and design, as that will help you determine what should and shouldn't be classes.
And, as others have pointed out, make sure you initialize your array list:
List<Integer> clist = new ArrayList<Integer>();
As for extending ArrayList vs. List, I would use ArrayList because 1. It has all the methods and functionality of List (because is is an implementation of List) and 2. It is backed by an array, which is what you are using. Just my preference, feel free to do some research and figure out what is going to work best for what you need; a List may be all you need, in which case, you should use that.
One other things I will point out, since it looks like you are creating a game, is that if you are going to pass and object, in your case and ArrayList, you are going to want to get familiar with the Parcelable interface. It is what will allow you to pass data from one activity to another. Here is a link that will get you started, along with a tutorial that might offer some insight to what is needed:
Tutorial for Parceleable:
http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/
Developer Info:
http://developer.android.com/reference/android/os/Parcelable.html
Best of luck!
I am making a calculator same as windows calculator. I am stuck at the history feature. which would be the best UI control to implement the history feature as seen in Windows Calculator?
I also want onclick events on the history.
I'm not sure how you represent a calculation, but you could have a simple class like this:
enum Operator {PLUS,MINUS,DIV,MULT};
class Calculation {
float operand1,operand2;
Operator operator;
public Calculation(float op1,float op2,Operator operator){
this.operand1=op1;
this.operand1=op2;
this.operator=operator;
}
}
Then when a calculation is done, create an object of this type and add it to an ArrayList:
List<Calculation> history = new ArrayList<Calculation>();// history
history.add(new Calculation(5,5,Operator.PLUS));// add a new `Calculation` to our list
Then access the list with history.get(some_integer), based on your UI.
Could you just use a List containing a number of previously entered calculations? If you knew the maximum possible history size in advance, you could just stick with a normal array, but a List will give you more flexibility.
You need to store all the operations and results with an index here. Increase the index every time when you perform an operation.To retrieve the past operation, manipulate the index and you can get the values.You can use Collection API for storing the operations.