This commit is contained in:
Ciro Santilli 2016-07-18 08:15:26 +01:00
parent 1155e8dd90
commit 9c088e08db
7 changed files with 376 additions and 96 deletions

View File

@ -61,6 +61,9 @@
1. [valarray](valarray.cpp)
1. [deque](deque.cpp)
1. [string](string.cpp)
1. IO
1. [sstream](sstream.cpp)
1. [iostream](iostream.cpp)
1. [thread](thread.cpp)
1. [sleep_for](sleep_for.cpp)
1. [atomic](atomic.cpp)

80
cpp/iostream.cpp Normal file
View File

@ -0,0 +1,80 @@
#include "common.hpp"
int main() {
/*
# cout
stdout.
`ostream` object.
For tests, std::stringstream shall be used as the results can then be tested,
and the behaviour is identical to cout.
`<<` is very magic. You need to understand:
- operator overload
- function template argument deduction
- namespaces adl
before really understanding why it works.
# cerr
Cout for stderr
# clog
By default also points to stderr, but can be redirected with TODO.
*/
{
std::cout << "cout" << std::endl;
std::cerr << "cerr" << std::endl;
std::clog << "clog" << std::endl;
}
/*
# cin
# stdin
`istream` object.
Avoid using it for similar reasons as scanf:
- hard to handle invalid inputs
- difficult to predict behaviour
getline is the best option.
*/
{
//std::cout << "Enter an integer:" << endl;
//std::cin >> i;
//std::cout << i << std::endl;
}
// This is how a very explicit usage of `<<` would look like
{
std::stringstream ss;
//TODO0 how to get his working?
//std::operator<<<std::ostream,std::string>(ss, "explicit");
std::operator<<(std::operator<<(ss, "explicit "), "call");
}
/*
# cout unsigned char
Prints literal bytes.
http://stackoverflow.com/questions/19562103/uint8-t-cant-be-printed-with-cout/19562163#19562163
*/
{
std::cout << (unsigned char)1 << std::endl;
std::cout << (char)1 << std::endl;
std::cout << (signed char)1 << std::endl;
std::cout << (int)1 << std::endl;
std::cout << (unsigned int)1 << std::endl;
}
}

View File

@ -286,67 +286,6 @@ int main() {
*/
{
/*
# cout
stdout.
`ostream` object.
For tests, std::stringstream shall be used as the results can then be tested,
and the behaviour is identical to cout.
`<<` is very magic. You need to understand:
- operator overload
- function template argument deduction
- namespaces adl
before really understanding why it works.
# cerr
Cout for stderr
# clog
By default also points to stderr, but can be redirected with TODO.
*/
{
std::cout << "cout" << std::endl;
std::cerr << "cerr" << std::endl;
std::clog << "clog" << std::endl;
}
/*
# cin
# stdin
`istream` object.
Avoid using it for similar reasons as scanf:
- hard to handle invalid inputs
- difficult to predict behaviour
getline is the best option.
*/
{
//std::cout << "Enter an integer:" << endl;
//std::cin >> i;
//std::cout << i << std::endl;
}
// This is how a very explicit usage of `<<` would look like
{
std::stringstream ss;
//TODO0 how to get his working?
//std::operator<<<std::ostream,std::string>(ss, "explicit");
std::operator<<(std::operator<<(ss, "explicit "), "call");
}
// #<< left shift overload
{

81
cpp/sstream.cpp Normal file
View File

@ -0,0 +1,81 @@
#include "common.hpp"
int main() {
/*
# stringstream
# basic_stringstream
http://en.cppreference.com/w/cpp/io/basic_stringstream
An iostream String backed implementation.
The following is defined:
typedef basic_stringstream<char> stringstream;
Very useful to test streams without creating files / stdin.
# ostringstream
TODO vs stringstream.
http://stackoverflow.com/questions/3292107/whats-the-difference-between-istringstream-ostringstream-and-stringstream-w
*/
{
// Initialize
{
{
std::stringstream ss("");
ss << "ab";
ss << "cd";
assert(ss.str() == "abcd");
}
// empty constructor: TODO everything fails to compile. Why?
{
std::stringstream ss();
//ss << "ab";
//ss << "cd";
//assert(ss.str() == "abcd");
}
// Nope, works like a file that has come content.
// http://stackoverflow.com/questions/3840531/what-is-the-purpose-of-ostringstreams-string-constructor
{
std::stringstream ss("ab");
ss << "cd";
assert(ss.str() == "cd");
}
// ostringstream + ate
{
std::ostringstream ss("ab", std::ios::ate);
ss << "cd";
assert(ss.str() == "abcd");
}
// stringstream + ate: TODO fails, why?
{
std::stringstream ss("ab", std::ios::ate);
ss << "cd";
assert(ss.str() == "ab");
}
}
// Clear
{
std::stringstream ss("");
// Clear stringstream
// http://stackoverflow.com/questions/20731/in-c-how-do-you-clear-a-stringstream-variable
ss.str("");
// Clear flags. Very important, not only for error indicators but also for end of stream.
ss.clear();
assert(ss.str() == "");
// ERROR: use of deleted function because the constructor is =delete.
//ss = std::stringstream();
}
}
}

View File

@ -217,38 +217,6 @@ int main() {
}
}
/*
# stringstream
# basic_stringstream
An iostream String backed implementation.
The following is defined:
typedef basic_stringstream<char> stringstream;
typedef basic_stringstream<char>
Very useful to test streams without creating files / stdin.
*/
{
std::stringstream oss("abcd");
// str does not clear the std::stringstream object
assert(oss.str() == "abcd");
// To clear it you could do: http://stackoverflow.com/questions/20731/in-c-how-do-you-clear-a-stringstream-variable
// Set to empty:
oss.str("");
// Clear flags. Very important, not only for error indicators but also for end of stream.
oss.clear();
assert(oss.str() == "");
// ERROR: use of deleted function because the constructor is =delete.
//oss = std::stringstream();
}
// Possible application: build up a huge string step by step.
// May be more efficient than concatenations which always generates new objects.
{
@ -263,7 +231,7 @@ int main() {
There are a few standard alternatives.
<http://stackoverflow.com/questions/5590381/easiest-way-to-convert-int-to-string-in-c>
http://stackoverflow.com/questions/5590381/easiest-way-to-convert-int-to-string-in-c
*/
{
/*
@ -299,8 +267,11 @@ int main() {
}
}
// #int to string
// http://stackoverflow.com/questions/7663709/convert-string-to-int-c
/*
# string to int
http://stackoverflow.com/questions/7663709/convert-string-to-int-c
*/
{
// Best C++11 error checking option: stoi
#if __cplusplus >= 201103L

View File

@ -10,6 +10,7 @@
1. [Animation](animation.c)
1. [Animation user control](animation_user_control.c)
1. [Animation user control discrete](animation_user_control_discrete.c)
1. [Two player discrete](two_player_discrete.c)
1. [Animation random walk](animation_random_walk.c)
1. [Plane wave](plane_wave.c)
1. [TTF](ttf.c)

205
sdl/two_player_discrete.c Normal file
View File

@ -0,0 +1,205 @@
/*
Player movements are not synchronized.
To do so, we could:
- discretize time into time windows
- check if a keypress was done in a time slot
- update all players at once
but that would lead to a delay between keypress and movement.
If the time windows are very small, the delay cannot be seen,
but then the players would move too fast in this discrete world.
*/
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <SDL2/SDL.h>
#define WINDOW_WIDTH 600
#define RECTS_PER_WINDOW (10)
#define RECT_WIDTH (WINDOW_WIDTH / RECTS_PER_WINDOW)
#define SCREENS_PER_SECOND 1.0
#define MOVE_DELAY_NORMAL 0.25
#define MOVE_DELAY_FAST (MOVE_DELAY_NORMAL / 4.0)
typedef struct {
unsigned int x;
unsigned int y;
int speed_x;
int speed_y;
double last_move_time_s;
} PlayerState;
unsigned int get_pos(int x, int speed) {
x = (x + speed) % RECTS_PER_WINDOW;
if (x < 0)
x += RECTS_PER_WINDOW;
return x;
}
void draw_player(
SDL_Renderer *renderer,
PlayerState *player_state,
double current_time_s,
double move_delay,
unsigned int r,
unsigned int g,
unsigned int b) {
SDL_Rect rect;
rect.w = RECT_WIDTH;
rect.h = RECT_WIDTH;
if ((player_state->speed_x || player_state->speed_y) && current_time_s - player_state->last_move_time_s > move_delay) {
player_state->x = get_pos(player_state->x, player_state->speed_x);
player_state->y = get_pos(player_state->y, player_state->speed_y);
player_state->last_move_time_s = current_time_s;
}
rect.x = player_state->x * RECT_WIDTH;
rect.y = player_state->y * RECT_WIDTH;
SDL_SetRenderDrawColor(renderer, r, g, b, 255);
SDL_RenderFillRect(renderer, &rect);
}
void init_state(
PlayerState *player_state_0,
PlayerState *player_state_1,
double *move_delay) {
*move_delay = MOVE_DELAY_NORMAL;
player_state_0->x = RECTS_PER_WINDOW / 5;
player_state_0->y = RECTS_PER_WINDOW / 2;
player_state_0->speed_x = 0;
player_state_0->speed_y = 0;
player_state_0->last_move_time_s = SDL_GetTicks() / 1000.0;
player_state_1->x = 4 * RECTS_PER_WINDOW / 5;
player_state_1->y = RECTS_PER_WINDOW / 2;
player_state_1->speed_x = 0;
player_state_1->speed_y = 0;
player_state_1->last_move_time_s = player_state_0->last_move_time_s;
}
int main(void) {
SDL_Event event;
SDL_Renderer *renderer;
SDL_Window *window;
double current_time_s;
double move_delay = MOVE_DELAY_NORMAL;
PlayerState player_state_0, player_state_1;
unsigned int current_time, last_time;
SDL_Init(SDL_INIT_TIMER | SDL_INIT_VIDEO);
SDL_CreateWindowAndRenderer(WINDOW_WIDTH, WINDOW_WIDTH, 0, &window, &renderer);
SDL_SetWindowTitle(window, "asdw: move red | jkli: move blue | space: move faster | esc: restart");
main_loop:
init_state(&player_state_0, &player_state_1, &move_delay);
while (1) {
current_time = SDL_GetTicks();
current_time_s = current_time / 1000.0;
while (SDL_PollEvent(&event) == 1) {
if (event.type == SDL_QUIT) {
goto quit;
} else if (event.type == SDL_KEYDOWN) {
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
goto main_loop;
case SDLK_SPACE:
move_delay = MOVE_DELAY_FAST;
break;
case SDLK_a:
player_state_0.speed_x = -1;
break;
case SDLK_d:
player_state_0.speed_x = 1;
break;
case SDLK_w:
player_state_0.speed_y = -1;
break;
case SDLK_s:
player_state_0.speed_y = 1;
break;
case SDLK_j:
player_state_1.speed_x = -1;
break;
case SDLK_l:
player_state_1.speed_x = 1;
break;
case SDLK_i:
player_state_1.speed_y = -1;
break;
case SDLK_k:
player_state_1.speed_y = 1;
break;
default:
break;
}
} else if (event.type == SDL_KEYUP) {
switch(event.key.keysym.sym) {
case SDLK_SPACE:
move_delay = MOVE_DELAY_NORMAL;
break;
case SDLK_a:
case SDLK_d:
player_state_0.speed_x = 0;
break;
case SDLK_w:
case SDLK_s:
player_state_0.speed_y = 0;
break;
case SDLK_j:
case SDLK_l:
player_state_1.speed_x = 0;
break;
case SDLK_i:
case SDLK_k:
player_state_1.speed_y = 0;
break;
default:
break;
}
}
}
if (current_time != last_time) {
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0);
SDL_RenderClear(renderer);
draw_player(
renderer,
&player_state_0,
current_time_s,
move_delay,
255,
0,
0
);
draw_player(
renderer,
&player_state_1,
current_time_s,
move_delay,
0,
0,
255
);
SDL_RenderPresent(renderer);
}
last_time = current_time;
}
quit:
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}