randnumber_mn.c 生成一个数组,包括k个不重复的整数,并且要求这些整数范围为[m,n),生成的结果中不能包含inum中的数字,size表示inum的长度

#include <stdlib.h>
#include <memory.h>
#include <time.h>

//---------------------------------------------------------
//位操作
enum { BITSPERWORD = 32, SHIFT = 5, MASK = 0x1F };

struct tagBitOption;
typedef struct tagBitOption BitOption;

struct tagBitOption {
	int (*init)(BitOption * bit, int m, int n, int k);
	void (*destroy)(BitOption ** bit);

	void (*set)(BitOption * bit, int i);
	void (*clr)(BitOption * bit, int i);
	int (*test)(BitOption * bit, int i);

	int m, n, k, *x;
};

static void set(BitOption * bit, int i)
{
	int t;
	if (bit && (i >= bit->m) && (i < bit->n)) {
		t = i - bit->m;
		bit->x[t>>SHIFT] |= (1 << (t & MASK));
	}
}

static void clr(BitOption * bit, int i)
{
	int t;
	if (bit && (i >= bit->m) && (i < bit->n)) {
		t = i - bit->m;
		bit->x[t>>SHIFT] &= ~(1 << (t & MASK));
	}
}

static int test(BitOption * bit, int i)
{
	int t;
	if (bit && (i >= bit->m) && (i < bit->n)) {
		t = i - bit->m;
		return bit->x[t>>SHIFT] & (1 << (t & MASK));
	}
	return 1;//若i不在范围[m,n),则认为i存在的,外面需要继续产生随机数
}

static int init(BitOption * bit, int m, int n, int k)
{
	int s;
	int ret = 0;
	if (bit) {
		bit->m = m;
		bit->n = n;
		bit->k = k;
		s = (1 + (n - m)/BITSPERWORD) * sizeof(int);
		bit->x = (int *)malloc(s);
		if (bit->x) {
			memset(bit->x, 0, s);
			ret = 1;//成功
		}
	}
	return ret;
}

static void destroy(BitOption ** bit)
{
	if (bit) {
		if (*bit) {
			if ((*bit)->x)
				free((*bit)->x);
			free(*bit);
			*bit = NULL;
		}
	}
}

//某些数字不能出现在随机数结果中,这里设置一下
static void setInvalidNumber(BitOption * bit, int * inum, int size)
{
	if (bit && inum && size > 0) {
		int i;
		for (i = 0; i < size; i++) {
			bit->set(bit, inum[i]);
		}
	}
}

static BitOption * createBitOption(int m, int n, int k) 
{
	BitOption * b = NULL;
	b = (BitOption *)malloc(sizeof(BitOption));
	if (b) {
		memset(b, 0, sizeof(BitOption));
		b->init = init;
		b->destroy = destroy;
		b->set = set;
		b->clr = clr;
		b->test = test;
		if (!b->init(b, m, n, k))
			b->destroy(&b);
	}
	return b;
}

//---------------------------------------------------------

//生成一个数组,包括k个不重复的整数,并且要求这些整数范围为[m,n)
//生成的结果中不能包含inum中的数字,size表示inum的长度
//m < n, k < n - m
int * RandNumberMN(int m, int n, int k, int * inum, int size)
{
	int i,t;
	int * result = NULL;
	BitOption * bit = NULL;
	int ok = 0;

	do {
		srand((int)time(NULL));
		if (m >= n || k > n - m)
			break;
		bit = createBitOption(m, n, k);
		if (NULL == bit)
			break;
		setInvalidNumber(bit, inum, size);
		result = malloc(k * sizeof(int));
		if (NULL == result)
			break;
		for (i = 0; i < k; i++) {
			while(bit->test(bit, t = rand()%(n-m+1)+m));
			result[i] = t;
			bit->set(bit, t);
		}
		ok = 1;
	} while (0);
	if (bit)
		bit->destroy(&bit);
	if (1 != ok) {
		if (result) {
			free(result);
			result = NULL;
		}
	} 
	return result;
}

//
//测试
#include <stdio.h>

void testRandMN(void)
{
	time_t start, end;
	int * result = NULL;
	int m = 490, n = 540, k = 10;
	int inum[] = {3, 90, 200, 305, 487, 503, 500, 501,502, 504};

	printf("m = %d, n = %d, k = %d\n", m, n, k);

	start = time(NULL);
	result = RandNumberMN(m, n, k, inum, sizeof(inum)/sizeof(inum[0]));
	end = time(NULL);
	printf("time = %d\n\n", end - start);

	if (result) {
		printf("RandNumber success!\n");
		if (k < 200) {//数量较小时,查看结果是否符合要求
			int i;
			for (i = 0; i < k; i++) {
				printf("%d, ", result[i]);
			}
			printf("\n");
		}
		free(result);
		result = NULL;
	} else {
		printf("RandNumber failed!\n\n");
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个简单的HTML版2048游戏的代码,可以供你参考: HTML代码: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>2048 Game</title> <style> #game-board { width: 400px; height: 400px; border: 1px solid #ccc; position: relative; margin: 0 auto; background-color: #eee; } .game-cell { position: absolute; width: 90px; height: 90px; border-radius: 5px; background-color: #ccc0b3; font-size: 36px; text-align: center; line-height: 90px; font-family: Arial, sans-serif; } .game-over { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background-color: #fff; padding: 20px; border-radius: 5px; box-shadow: 0 0 10px #ccc; font-size: 24px; text-align: center; font-family: Arial, sans-serif; display: none; } </style> </head> <body> <div id="game-board"></div> <div class="game-over">Game Over!</div> <script src="game.js"></script> </body> </html> ``` JavaScript代码: ```javascript var board = new Array(); var score = 0; var hasConflicted = new Array(); $(document).ready(function() { newgame(); }); function newgame() { // 初始化棋盘 init(); // 在随机两个格子生成数字 generateOneNumber(); generateOneNumber(); } function init() { for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { var gridCell = $("#grid-cell-" + i + "-" + j); gridCell.css('top', getPosTop(i, j)); gridCell.css('left', getPosLeft(i, j)); } } for (var i = 0; i < 4; i++) { board[i] = new Array(); hasConflicted[i] = new Array(); for (var j = 0; j < 4; j++) { board[i][j] = 0; hasConflicted[i][j] = false; } } updateBoardView(); score = 0; $('#score').text(score); $('.game-over').hide(); } function updateBoardView() { $('.number-cell').remove(); for (var i = 0; i < 4; i++) { for (var j = 0; j < 4; j++) { $('#game-board').append('<div class="number-cell" id="number-cell-' + i + '-' + j + '"></div>'); var theNumberCell = $('#number-cell-' + i + '-' + j); if (board[i][j] == 0) { theNumberCell.css('width', '0px'); theNumberCell.css('height', '0px'); theNumberCell.css('top', getPosTop(i, j) + 45); theNumberCell.css('left', getPosLeft(i, j) + 45); } else { theNumberCell.css('width', '90px'); theNumberCell.css('height', '90px'); theNumberCell.css('top', getPosTop(i, j)); theNumberCell.css('left', getPosLeft(i, j)); theNumberCell.css('background-color', getNumberBackgroundColor(board[i][j])); theNumberCell.css('color', getNumberColor(board[i][j])); theNumberCell.text(board[i][j]); } hasConflicted[i][j] = false; } } $('.number-cell').css('line-height', '90px'); $('.number-cell').css('font-size', '36px'); } function generateOneNumber() { if (nospace(board)) { return false; } // 随机一个位置 var randX = parseInt(Math.floor(Math.random() * 4)); var randY = parseInt(Math.floor(Math.random() * 4)); while (true) { if (board[randX][randY] == 0) { break; } randX = parseInt(Math.floor(Math.random() * 4)); randY = parseInt(Math.floor(Math.random() * 4)); } // 随机一个数字 var randNumber = Math.random() < 0.5 ? 2 : 4; // 在随机位置显示随机数字 board[randX][randY] = randNumber; showNumberWithAnimation(randX, randY, randNumber); return true; } $(document).keydown(function(event) { switch (event.keyCode) { case 37: // left event.preventDefault(); if (moveLeft()) { setTimeout("generateOneNumber()", 210); setTimeout("isGameOver()", 300); } break; case 38: // up event.preventDefault(); if (moveUp()) { setTimeout("generateOneNumber()", 210); setTimeout("isGameOver()", 300); } break; case 39: // right event.preventDefault(); if (moveRight()) { setTimeout("generateOneNumber()", 210); setTimeout("isGameOver()", 300); } break; case 40: // down event.preventDefault(); if (moveDown()) { setTimeout("generateOneNumber()", 210); setTimeout("isGameOver()", 300); } break; default: break; } }); function isGameOver() { if (nospace(board) && nomove(board)) { gameOver(); } } function gameOver() { $('.game-over').show(); } function moveLeft() { if (!canMoveLeft(board)) { return false; } // moveLeft for (var i = 0; i < 4; i++) { for (var j = 1; j < 4; j++) { if (board[i][j] != 0) { for (var k = 0; k < j; k++) { if (board[i][k] == 0 && noBlockHorizontal(i, k, j, board)) { // move showMoveAnimation(i, j, i, k); board[i][k] = board[i][j]; board[i][j] = 0; continue; } else if (board[i][k] == board[i][j] && noBlockHorizontal(i, k, j, board) && !hasConflicted[i][k]) { // move and merge showMoveAnimation(i, j, i, k); board[i][k] += board[i][j]; board[i][j] = 0; score += board[i][k]; $('#score').text(score); hasConflicted[i][k] = true; continue; } } } } } setTimeout("updateBoardView()", 200); return true; } function moveRight() { if (!canMoveRight(board)) { return false; } // moveRight for (var i = 0; i < 4; i++) { for (var j = 2; j >= 0; j--) { if (board[i][j] != 0) { for (var k = 3; k > j; k--) { if (board[i][k] == 0 && noBlockHorizontal(i, j, k, board)) { // move showMoveAnimation(i, j, i, k); board[i][k] = board[i][j]; board[i][j] = 0; continue; } else if (board[i][k] == board[i][j] && noBlockHorizontal(i, j, k, board) && !hasConflicted[i][k]) { // move and merge showMoveAnimation(i, j, i, k); board[i][k] += board[i][j]; board[i][j] = 0; score += board[i][k]; $('#score').text(score); hasConflicted[i][k] = true; continue; } } } } } setTimeout("updateBoardView()", 200); return true; } function moveUp() { if (!canMoveUp(board)) { return false; } // moveUp for (var j = 0; j < 4; j++) { for (var i = 1; i < 4; i++) { if (board[i][j] != 0) { for (var k = 0; k < i; k++) { if (board[k][j] == 0 && noBlockVertical(j, k, i, board)) { // move showMoveAnimation(i, j, k, j); board[k][j] = board[i][j]; board[i][j] = 0; continue; } else if (board[k][j] == board[i][j] && noBlockVertical(j, k, i, board) && !hasConflicted[k][j]) { // move and merge showMoveAnimation(i, j, k, j); board[k][j] += board[i][j]; board[i][j] = 0; score += board[k][j]; $('#score').text(score); hasConflicted[k][j] = true; continue; } } } } } setTimeout("updateBoardView()", 200); return true; } function moveDown() { if (!canMoveDown(board)) { return false; } // moveDown for (var j = 0; j < 4; j++) { for (var i = 2; i >= 0; i--) { if (board[i][j] != 0) { for (var k = 3; k > i; k--) { if (board[k][j] == 0 && noBlockVertical(j, i, k, board)) { // move showMoveAnimation(i, j, k, j); board[k][j] = board[i][j]; board[i][j] = 0; continue; } else if (board[k][j] == board[i][j] && noBlockVertical(j, i, k, board) && !hasConflicted[k][j]) { // move and merge showMoveAnimation(i, j, k, j); board[k][j] += board[i][j]; board[i][j] = 0; score += board[k][j]; $('#score').text(score); hasConflicted[k][j] = true; continue; } } } } } setTimeout("updateBoardView()", 200); return true; } ``` 这段代码实现了2048游戏的基本功能,包括游戏面板的初始化、随机生成数字、移动方块、合并方块、更新分数、判断游戏是否结束等。你可以将代码保存为game.js文件,与HTML文件一起使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值