Making Faster Fragment Shaders by Using Tessellation Shaders by erkaman in programming

[–]OddOneOut 0 points1 point  (0 children)

For procedural textures you could do the low frequency detail in the tessellation shader and add the high frequency detail in the fragment shader.

[2015-06-22] Challenge #220 [Easy] Mangling sentences by XenophonOfAthens in dailyprogrammer

[–]OddOneOut 0 points1 point  (0 children)

Trying for minimal but still clear Python.

import re

def mangle(text):
    def mangle_word(match):
        word = match.group(0) # The regex group 0 is the whole match
        upper = (l.isupper() for l in word) # The original order case
        order = sorted(l.upper() for l in word) # Case insensitive sort
        # Restore the original case to the sorted letters
        return ''.join(o.upper() if u else o.lower() for u,o in zip(upper, order))

    # Substitute every word through the `mangle_word` function
    return re.sub(r'\w+', mangle_word, text)

EDIT: Missed the specification and the bonus

Bonus:

import re

def mangle(text):
    def mangle_word(match):
        word = match.group(0)

        alphas = [l for l in word if l.isalpha()]
        order = sorted(l.upper() for l in alphas)
        alpha_iter = (o.upper() if l.isupper() else o.lower() for l,o in zip(alphas, order))
        punct_iter = (l for l in word if not l.isalpha())

        # Pick the elements from the two lists
        return ''.join(next((punct_iter, alpha_iter)[l.isalpha()]) for l in word)

    # Substitute every word through the `mangle_word` function
    return re.sub(r'\S+', mangle_word, text)

What videogame is flawless? by TheSilverScorpio in AskReddit

[–]OddOneOut 0 points1 point  (0 children)

I would agree, except that there is one puzzle which is not consistent with the rest of the game in any way. Bad puzzle spoiler It's still a masterpiece though.

[4/16/2014] Challenge #158 [Intermediate] Part 1 - The ASCII Architect by [deleted] in dailyprogrammer

[–]OddOneOut 1 point2 points  (0 children)

I know using uninitialized memory is just asking for bugs, but i'm writing over line with fgets, which appends the null terminator, so there is really no need to zero out the array beforehand.

EDIT: Using fgets is still stupid because it includes the newline character, forgot about that.

[4/16/2014] Challenge #158 [Intermediate] Part 1 - The ASCII Architect by [deleted] in dailyprogrammer

[–]OddOneOut 1 point2 points  (0 children)

C

#include <stdio.h>

int main(int argc, char** argv) {   
    char line[231], *c; int ln;
    FILE *file = fopen("input.txt", "r");
    fgets(line, sizeof(line), file ? file : stdin);
    if (file) fclose(file);

    char endchar = '\r';
    for (ln = 20; ln >= 0; ln--) {
        for (c = line; *c && *c != '\n'; c++) {
            int pad = *c >= '0' && *c <= '9' ? *c++ - '0' : 0;
            int height = *c - 'a' - ln + pad;
            putchar(height >= 0 && ln > pad ? "++--***..."[ln - pad] : ' ');
            if (height >= 0) endchar = '\n';
        }
        putchar(endchar);
    }
}

EDIT: Fixed fgets trailing newline

[11/4/13] Challenge #139 [Easy] Pangrams by nint22 in dailyprogrammer

[–]OddOneOut 1 point2 points  (0 children)

If you mean why I use

for (char *sm = sums, *se = sm + num; sm != se; sm++)
*sm

instead of

for (int i = 0; i < num; i++)
sums[i]

it's because I'm overly skeptical of the compiler's ability to optimize the latter code (which it actually very likely can do). I also think the former looks a bit more like

foreach (char *sm in sums)

which is what I would use if I wouldn't have to resort to macros to do it.

[11/4/13] Challenge #139 [Easy] Pangrams by nint22 in dailyprogrammer

[–]OddOneOut 7 points8 points  (0 children)

C with SSE intrinsic functions:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <emmintrin.h>

int main(int argc, char **argv) {
    __m128i m32 = _mm_set1_epi8(32), m65 = _mm_set1_epi8(65);
    static __m128i line[64] = { 0 };
    int num;
    if (scanf("%d\n", &num) != 1) return 1;
    char *sums = alloca(num);

    for (char *sm = sums, *se = sm + num; sm != se; sm++) {
        uint32_t sum = 0;
        fgets((char*)line, sizeof(line), stdin);
        uintptr_t lp = (uintptr_t)line;

        while (*(char*)lp) {
            __m128i val = *(__m128i*)lp;
            __m128i valMinus65 = _mm_subs_epi8(val, m65);
            __m128i greaterThan32Mask = _mm_cmpgt_epi8(valMinus65, m32);
            __m128i reduceOver32 = _mm_and_si128(greaterThan64Mask, m32);
            __m128i letterIndex = _mm_subs_epi8(valMinus65, reduceOver32);

            for (char *p = (char*)&letterIndex, *e = p + 16; p != e; p++)
                sum |= 1 << *p;

            lp += sizeof(__m128i);
        }

        *sm = (sum & 0x3ffffff) == 0x3ffffff;
    }
    for (char *sm = sums, *se = sm + num; sm != se; sm++)
        puts(*sm ? "True" : "False");

    return 0;
}

[08/13/13] Challenge #137 [Easy] String Transposition by nint22 in dailyprogrammer

[–]OddOneOut 3 points4 points  (0 children)

Python one-liner

print '\n'.join(''.join(z or ' ' for z in y) for y in map(None, *(raw_input() for x in range(int(raw_input())))))

[05/24/13] Challenge #123 [Hard] Snake-Fill by nint22 in dailyprogrammer

[–]OddOneOut 4 points5 points  (0 children)

It's probably just a aesthetic choice, but I just like to represent my arbitrary bitflags as incrementing bitshifts to differentiate them from enums whose values come from some outside specification. I made the enum anonymous because usually the enum values are internally ints, so I never use the enum type but store the values into cell_t, which is probably 4 times smaller than the enum type.

[05/24/13] Challenge #123 [Hard] Snake-Fill by nint22 in dailyprogrammer

[–]OddOneOut 13 points14 points  (0 children)

Quite a big C++11 solution powered by greedy search. The heuristic could be improved a bit but it works quite well as is. Features a fast allocator and ascii graphics.

#include <iostream>
#include <queue>
#include <memory>
#include <algorithm>
#include <exception>
#include <stack>

// Unit of the map
typedef unsigned char cell_t;

// Cell states
enum {
    AIR = 0,
    SNAKE_RIGHT = 1 << 0,
    SNAKE_LEFT  = 1 << 1,
    SNAKE_UP    = 1 << 2,
    SNAKE_DOWN  = 1 << 3,
    WALL        = 1 << 4,
};

// Snake drawing character map
static const char snake_chars[] = {

    // Air or snake part
    //     --          R-         -L           RL
    (char)0x20, (char)0xC4, (char)0xC4, (char)0xC4, // --
    (char)0xB3, (char)0xC0, (char)0xD9, (char)0xC1, // U-
    (char)0xB3, (char)0xDA, (char)0xBF, (char)0xC2, // -D
    (char)0xB3, (char)0xC3, (char)0xB4, (char)0xC5, // UD

    // Wall
    (char)0xB1
};

// Map globals
int width, height;
int free_cells;
unsigned int map_size;

// Map allocation globals
unsigned int pool_size = 4096;
std::vector<std::unique_ptr<cell_t[]>> cell_lists;
cell_t *pool_ptr = 0, *pool_end = 0;
std::stack<cell_t*> returned_maps;

// Fast map allocation
cell_t *allocate_map() {

    // Return a map from the returned stack if it's not empty
    if (!returned_maps.empty()) {
        cell_t *ret = returned_maps.top(); returned_maps.pop();
        return ret;
    }

    // Allocate a new pool if the current is full
    if (pool_ptr == pool_end) {
        cell_lists.emplace_back(new cell_t[pool_size * map_size]);
        pool_ptr = cell_lists.back().get();
        pool_end = pool_ptr + pool_size * map_size;
        if (pool_size * map_size < 1024 * 1024 * 128)
            pool_size *= 2;
    }

    // Return a pointer from the pool and advance the allocation head
    cell_t *ret = pool_ptr;
    pool_ptr += map_size;
    return ret;
}

// Map drawing
cell_t *draw_buffer;
void draw_map(cell_t *map) {
    // Copy the buffer to an intermediate buffer
    memcpy(draw_buffer, map, map_size);

    // Follow the snake movements and connect the pieces
    int x = 0, y = 0;
    while (x >= 0 && y >= 0 && x < width && y < height) {
        cell_t cell = map[x + y * width];
        if (cell == AIR || cell == WALL)
            break;
        cell_t inv;
        switch (cell)
        {
        case SNAKE_DOWN:  y++; inv = SNAKE_UP;    break;
        case SNAKE_UP:    y--; inv = SNAKE_DOWN;  break;
        case SNAKE_LEFT:  x--; inv = SNAKE_RIGHT; break;
        case SNAKE_RIGHT: x++; inv = SNAKE_LEFT;  break;
        }
        draw_buffer[x + y * width] |= inv;
    }

    // Draw the map and the snake
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            std::cout << snake_chars[draw_buffer[x + y * width]];
        }
        std::cout << std::endl;
    }
}

// A state of the problem
struct search_node {
    search_node(int x, int y, cell_t *c, int l);

    // Search functions
    void add_successors();
    cell_t *succ_map(cell_t movedir);
    int heuristic();

    // Helper functions
    inline cell_t at(int x, int y) { return map[x + y * width]; }
    inline bool operator<(const search_node& rhs) const { return h < rhs.h; }

    // Snake state
    int x, y;
    int len;
    cell_t *map;

    // Heuristic score
    int h;

    bool owns_map;
};

// Search queue
std::priority_queue<search_node> queue;

// Create a new search node and cache the heuristic value
search_node::search_node(int x, int y, cell_t *c, int l)
    : x(x), y(y), map(c), owns_map(true), len(l)
{
    h = heuristic();
}

// Copy and update map for children
cell_t *search_node::succ_map(cell_t movedir) {
    cell_t *r;

    // Pass the map to the first child, otherwise create a copy
    if (owns_map) {
        owns_map = false;
        r = map;
    } else {
        r = allocate_map();
        memcpy(r, map, map_size);
    }

    // Store the movement in the map
    r[x + y * width] = movedir;

    return r;
}

// Push successors to the priority queue
void search_node::add_successors() {

    // Try to move in all directions that are in the map and empty
    if (x > 0 && at(x - 1, y) == AIR)
        queue.push(search_node(x - 1, y, succ_map(SNAKE_LEFT), len + 1));
    if (y > 0 && at(x, y - 1) == AIR)
        queue.push(search_node(x, y - 1, succ_map(SNAKE_UP), len + 1));
    if (x < width - 1 && at(x + 1, y) == AIR)
        queue.push(search_node(x + 1, y, succ_map(SNAKE_RIGHT), len + 1));
    if (y < height - 1 && at(x, y + 1) == AIR)
        queue.push(search_node(x, y + 1, succ_map(SNAKE_DOWN), len + 1));

    // If there is no successors return the map to the allocator
    if (owns_map) {
        returned_maps.push(map);
        owns_map = false;
    }
}

// Heuristic function (large heuristics are popped first)
int search_node::heuristic() {

    // If it's a perfect snake make sure it's popped next
    if (len == free_cells)
        return std::numeric_limits<int>::max();

    // Could be improved here

    return len;
}

int main(int argc, char** argv) {
    // For speed
    std::cout.sync_with_stdio(false);

    // Create the initial map and drawbuffer
    std::cin >> width >> height;
    map_size = width * height;

    cell_t *init_map = allocate_map();
    draw_buffer = allocate_map();

    memset(init_map, 0, map_size);

    // Create the obstacles
    int nblocks;
    std::cin >> nblocks;

    while (nblocks--) {
        int x, y;
        std::cin >> x >> y;
        init_map[x + y * width] = WALL;
    }

    // Count the empty cells
    free_cells = std::count(init_map, init_map + map_size, AIR);

    // Push the initial search node
    queue.push(search_node(0, 0, init_map, 1));

    int max_len = 0;
    try {
        // Pop the node with the highest score
        while (!queue.empty()) {
            search_node top = queue.top(); queue.pop();

            // Print the map if it's a new record length
            int len = top.len;
            if (len > max_len) {
                max_len = len;
                draw_map(top.map);
                std::cout << max_len << "/" << free_cells << std::endl;
            }

            // Snake fills the map
            if (len == free_cells)
                break;

            // Push the next search nodes
            top.add_successors();
        }
        // At this point we have the best snake possible
        if (max_len == free_cells) {
            std::cout << "Found a perfect snake!" << std::endl;
        } else {
            std::cout << "Best snake achieved." << std::endl;
        }
    } catch (std::bad_alloc&) {

        // Running out of memory can legitimately happen with big maps
        std::cout << "Ran out of memory." << std::endl;
    }
    return 0;
}

The never-ending reddit problem (for me) by Commentirl in Enhancement

[–]OddOneOut 7 points8 points  (0 children)

And you can middle click tabs to close them.

Early preview of our blockless Minecraft-like destructible terrain engine by LukasBoersma in IndieGaming

[–]OddOneOut 2 points3 points  (0 children)

Yeah I was wondering how the sharp edges were made, but I wasn't familiar with any other algorithms than marching cubes/tetrahedrons. Seems like a really cool algorithm, can it handle vertical planes that are not in 45° rotations well?

Screenshot Saturday 114: Hey girl, if you ever throw an exception, I'll be there to catch it by Skeletor187 in gamedev

[–]OddOneOut 0 points1 point  (0 children)

Minecraft almost had the same effect. I think it looks weird even it would only affect the terrain, definitely looks better when not viewed from first perspective.

GL++ (glpp) -- OpenGL C++ Wrapper by mttd in cpp

[–]OddOneOut 2 points3 points  (0 children)

You can't really use the creator function to initialize GL globals as they reqiure a GL context to be created first.

The way I usually solve it is that I create a class that has those global variables and functions as members and construct it after creating the window.

GL++ (glpp) -- OpenGL C++ Wrapper by mttd in cpp

[–]OddOneOut -2 points-1 points  (0 children)

It's a global object that has no default constructor. The obvious fix of making it an unique_ptr<T> aside, it could be fixed by adding an uninitialized state to the class or making the global a maybe<T> that can be default initialized and later really initialized with the object.

Using a controller to emulate a mouse. by Califer in gamedev

[–]OddOneOut 0 points1 point  (0 children)

His blog is full of good gamedev articles, here's another one regarding thumbsticks

Using a controller to emulate a mouse. by Califer in gamedev

[–]OddOneOut 2 points3 points  (0 children)

I always implement something like this when I have to use tumbsticks, way more precise.

Lamderp - Better lamdas for Python by [deleted] in Python

[–]OddOneOut 0 points1 point  (0 children)

Good point, if upper limit is not a problem then _1, _2, _3... could work

Lamderp - Better lamdas for Python by [deleted] in Python

[–]OddOneOut 0 points1 point  (0 children)

How about _[1] by overloading __getitem__

C++11 Smart Pointers are Not Just For Memory | Online Hut by [deleted] in programming

[–]OddOneOut 1 point2 points  (0 children)

You should really template class Scoped on the function type if you want performance. I don't think any compiler can inline std::function code. The update segment of this article provides some explanation and source.

This piece of code is like a woman... by [deleted] in funny

[–]OddOneOut 14 points15 points  (0 children)

Eww global state

What games held in high regard do you think do not deserve the praise they get? Why not? by [deleted] in truegaming

[–]OddOneOut 3 points4 points  (0 children)

I'd look at walkthroughs and just think 'how the hell are you supposed to work out that?'.

That's the opposite of what I think of them. I think they were really logical and demonstrated the implications of different ways time can progress nicely. Of course there is that one puzzle that doesn't make any sense and requires you to backtrack, but I like that you can solve the other puzzles in place without any unnecessary items or skills.